xref: /aosp_15_r20/external/ltp/lib/tst_res.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker  *    AUTHOR            : Kent Rogers (from Dave Fenner's original)
4*49cdfc7eSAndroid Build Coastguard Worker  *    CO-PILOT          : Rich Logan
5*49cdfc7eSAndroid Build Coastguard Worker  *    DATE STARTED      : 05/01/90 (rewritten 1/96)
6*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2009-2016 Cyril Hrubis <[email protected]>
7*49cdfc7eSAndroid Build Coastguard Worker  *
8*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
9*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of version 2 of the GNU General Public License as
10*49cdfc7eSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
11*49cdfc7eSAndroid Build Coastguard Worker  *
12*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it would be useful, but
13*49cdfc7eSAndroid Build Coastguard Worker  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15*49cdfc7eSAndroid Build Coastguard Worker  *
16*49cdfc7eSAndroid Build Coastguard Worker  * Further, this software is distributed without any warranty that it is
17*49cdfc7eSAndroid Build Coastguard Worker  * free of the rightful claim of any third person regarding infringement
18*49cdfc7eSAndroid Build Coastguard Worker  * or the like.  Any license provided herein, whether implied or
19*49cdfc7eSAndroid Build Coastguard Worker  * otherwise, applies only to this software file.  Patent licenses, if
20*49cdfc7eSAndroid Build Coastguard Worker  * any, provided herein do not apply to combinations of this program with
21*49cdfc7eSAndroid Build Coastguard Worker  * other software, or any other product whatsoever.
22*49cdfc7eSAndroid Build Coastguard Worker  *
23*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
24*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write the Free Software Foundation, Inc.,
25*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26*49cdfc7eSAndroid Build Coastguard Worker  *
27*49cdfc7eSAndroid Build Coastguard Worker  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
28*49cdfc7eSAndroid Build Coastguard Worker  * Mountain View, CA  94043, or:
29*49cdfc7eSAndroid Build Coastguard Worker  *
30*49cdfc7eSAndroid Build Coastguard Worker  * http://www.sgi.com
31*49cdfc7eSAndroid Build Coastguard Worker  *
32*49cdfc7eSAndroid Build Coastguard Worker  * For further information regarding this notice, see:
33*49cdfc7eSAndroid Build Coastguard Worker  *
34*49cdfc7eSAndroid Build Coastguard Worker  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
35*49cdfc7eSAndroid Build Coastguard Worker  */
36*49cdfc7eSAndroid Build Coastguard Worker 
37*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
38*49cdfc7eSAndroid Build Coastguard Worker 
39*49cdfc7eSAndroid Build Coastguard Worker #include <pthread.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include <assert.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
43*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
44*49cdfc7eSAndroid Build Coastguard Worker #include <stdarg.h>
45*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
48*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
49*49cdfc7eSAndroid Build Coastguard Worker 
50*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
51*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
52*49cdfc7eSAndroid Build Coastguard Worker #include "usctest.h"
53*49cdfc7eSAndroid Build Coastguard Worker #include "ltp_priv.h"
54*49cdfc7eSAndroid Build Coastguard Worker #include "tst_ansi_color.h"
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker long TEST_RETURN;
57*49cdfc7eSAndroid Build Coastguard Worker int TEST_ERRNO;
58*49cdfc7eSAndroid Build Coastguard Worker void *TST_RET_PTR;
59*49cdfc7eSAndroid Build Coastguard Worker 
60*49cdfc7eSAndroid Build Coastguard Worker #define VERBOSE      1
61*49cdfc7eSAndroid Build Coastguard Worker #define NOPASS       3
62*49cdfc7eSAndroid Build Coastguard Worker #define DISCARD      4
63*49cdfc7eSAndroid Build Coastguard Worker 
64*49cdfc7eSAndroid Build Coastguard Worker #define MAXMESG      80		/* max length of internal messages */
65*49cdfc7eSAndroid Build Coastguard Worker #define USERMESG     2048	/* max length of user message */
66*49cdfc7eSAndroid Build Coastguard Worker #define TRUE         1
67*49cdfc7eSAndroid Build Coastguard Worker #define FALSE        0
68*49cdfc7eSAndroid Build Coastguard Worker 
69*49cdfc7eSAndroid Build Coastguard Worker /*
70*49cdfc7eSAndroid Build Coastguard Worker  * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result
71*49cdfc7eSAndroid Build Coastguard Worker  *                   message into the specified string.
72*49cdfc7eSAndroid Build Coastguard Worker  *
73*49cdfc7eSAndroid Build Coastguard Worker  * NOTE (garrcoop):  arg_fmt _must_ be the last element in each function
74*49cdfc7eSAndroid Build Coastguard Worker  *		     argument list that employs this.
75*49cdfc7eSAndroid Build Coastguard Worker  */
76*49cdfc7eSAndroid Build Coastguard Worker #define EXPAND_VAR_ARGS(buf, arg_fmt, buf_len) do {\
77*49cdfc7eSAndroid Build Coastguard Worker 	va_list ap;				\
78*49cdfc7eSAndroid Build Coastguard Worker 	assert(arg_fmt != NULL);		\
79*49cdfc7eSAndroid Build Coastguard Worker 	va_start(ap, arg_fmt);			\
80*49cdfc7eSAndroid Build Coastguard Worker 	vsnprintf(buf, buf_len, arg_fmt, ap);	\
81*49cdfc7eSAndroid Build Coastguard Worker 	va_end(ap);				\
82*49cdfc7eSAndroid Build Coastguard Worker 	assert(strlen(buf) > 0);		\
83*49cdfc7eSAndroid Build Coastguard Worker } while (0)
84*49cdfc7eSAndroid Build Coastguard Worker 
85*49cdfc7eSAndroid Build Coastguard Worker #if !defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(__ANDROID__)
86*49cdfc7eSAndroid Build Coastguard Worker #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
87*49cdfc7eSAndroid Build Coastguard Worker #endif
88*49cdfc7eSAndroid Build Coastguard Worker 
89*49cdfc7eSAndroid Build Coastguard Worker #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
90*49cdfc7eSAndroid Build Coastguard Worker static pthread_mutex_t tmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
91*49cdfc7eSAndroid Build Coastguard Worker #else
92*49cdfc7eSAndroid Build Coastguard Worker static pthread_mutex_t tmutex;
93*49cdfc7eSAndroid Build Coastguard Worker 
94*49cdfc7eSAndroid Build Coastguard Worker __attribute__((constructor))
init_tmutex(void)95*49cdfc7eSAndroid Build Coastguard Worker static void init_tmutex(void)
96*49cdfc7eSAndroid Build Coastguard Worker {
97*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutexattr_t mutattr = {0};
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutexattr_init(&mutattr);
100*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutexattr_settype(&mutattr, PTHREAD_MUTEX_RECURSIVE);
101*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_init(&tmutex, &mutattr);
102*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutexattr_destroy(&mutattr);
103*49cdfc7eSAndroid Build Coastguard Worker }
104*49cdfc7eSAndroid Build Coastguard Worker #endif
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker static void check_env(void);
107*49cdfc7eSAndroid Build Coastguard Worker static void tst_condense(int tnum, int ttype, const char *tmesg);
108*49cdfc7eSAndroid Build Coastguard Worker static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg);
109*49cdfc7eSAndroid Build Coastguard Worker 
110*49cdfc7eSAndroid Build Coastguard Worker static int T_exitval = 0;	/* exit value used by tst_exit() */
111*49cdfc7eSAndroid Build Coastguard Worker static int passed_cnt;
112*49cdfc7eSAndroid Build Coastguard Worker static int T_mode = VERBOSE;	/* flag indicating print mode: VERBOSE, */
113*49cdfc7eSAndroid Build Coastguard Worker 				/* NOPASS, DISCARD */
114*49cdfc7eSAndroid Build Coastguard Worker 
115*49cdfc7eSAndroid Build Coastguard Worker static char Warn_mesg[MAXMESG];	/* holds warning messages */
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker /*
118*49cdfc7eSAndroid Build Coastguard Worker  * These are used for condensing output when NOT in verbose mode.
119*49cdfc7eSAndroid Build Coastguard Worker  */
120*49cdfc7eSAndroid Build Coastguard Worker static int Buffered = FALSE;	/* TRUE if condensed output is currently */
121*49cdfc7eSAndroid Build Coastguard Worker 				/* buffered (i.e. not yet printed) */
122*49cdfc7eSAndroid Build Coastguard Worker static char *Last_tcid;		/* previous test case id */
123*49cdfc7eSAndroid Build Coastguard Worker static int Last_num;		/* previous test case number */
124*49cdfc7eSAndroid Build Coastguard Worker static int Last_type;		/* previous test result type */
125*49cdfc7eSAndroid Build Coastguard Worker static char *Last_mesg;		/* previous test result message */
126*49cdfc7eSAndroid Build Coastguard Worker 
127*49cdfc7eSAndroid Build Coastguard Worker int tst_count = 0;
128*49cdfc7eSAndroid Build Coastguard Worker 
129*49cdfc7eSAndroid Build Coastguard Worker /*
130*49cdfc7eSAndroid Build Coastguard Worker  * These globals must be defined in the test.
131*49cdfc7eSAndroid Build Coastguard Worker  */
132*49cdfc7eSAndroid Build Coastguard Worker extern char *TCID;		/* Test case identifier from the test source */
133*49cdfc7eSAndroid Build Coastguard Worker extern int TST_TOTAL;		/* Total number of test cases from the test */
134*49cdfc7eSAndroid Build Coastguard Worker 
135*49cdfc7eSAndroid Build Coastguard Worker 
136*49cdfc7eSAndroid Build Coastguard Worker struct pair {
137*49cdfc7eSAndroid Build Coastguard Worker 	const char *name;
138*49cdfc7eSAndroid Build Coastguard Worker 	int val;
139*49cdfc7eSAndroid Build Coastguard Worker };
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker #define PAIR(def) [def] = {.name = #def, .val = def},
142*49cdfc7eSAndroid Build Coastguard Worker #define STRPAIR(key, value) [key] = {.name = value, .val = key},
143*49cdfc7eSAndroid Build Coastguard Worker 
144*49cdfc7eSAndroid Build Coastguard Worker #define PAIR_LOOKUP(pair_arr, idx) do {                       \
145*49cdfc7eSAndroid Build Coastguard Worker 	if (idx < 0 || (size_t)idx >= ARRAY_SIZE(pair_arr) || \
146*49cdfc7eSAndroid Build Coastguard Worker 	    pair_arr[idx].name == NULL)                       \
147*49cdfc7eSAndroid Build Coastguard Worker 		return "???";                                 \
148*49cdfc7eSAndroid Build Coastguard Worker 	return pair_arr[idx].name;                            \
149*49cdfc7eSAndroid Build Coastguard Worker } while (0)
150*49cdfc7eSAndroid Build Coastguard Worker 
strttype(int ttype)151*49cdfc7eSAndroid Build Coastguard Worker const char *strttype(int ttype)
152*49cdfc7eSAndroid Build Coastguard Worker {
153*49cdfc7eSAndroid Build Coastguard Worker 	static const struct pair ttype_pairs[] = {
154*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TPASS)
155*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TFAIL)
156*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TBROK)
157*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TCONF)
158*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TWARN)
159*49cdfc7eSAndroid Build Coastguard Worker 		PAIR(TINFO)
160*49cdfc7eSAndroid Build Coastguard Worker 	};
161*49cdfc7eSAndroid Build Coastguard Worker 
162*49cdfc7eSAndroid Build Coastguard Worker 	PAIR_LOOKUP(ttype_pairs, TTYPE_RESULT(ttype));
163*49cdfc7eSAndroid Build Coastguard Worker }
164*49cdfc7eSAndroid Build Coastguard Worker 
165*49cdfc7eSAndroid Build Coastguard Worker #include "errnos.h"
166*49cdfc7eSAndroid Build Coastguard Worker #include "signame.h"
167*49cdfc7eSAndroid Build Coastguard Worker 
tst_res__(const char * file,const int lineno,int ttype,const char * arg_fmt,...)168*49cdfc7eSAndroid Build Coastguard Worker static void tst_res__(const char *file, const int lineno, int ttype,
169*49cdfc7eSAndroid Build Coastguard Worker                       const char *arg_fmt, ...)
170*49cdfc7eSAndroid Build Coastguard Worker {
171*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&tmutex);
172*49cdfc7eSAndroid Build Coastguard Worker 
173*49cdfc7eSAndroid Build Coastguard Worker 	char tmesg[USERMESG];
174*49cdfc7eSAndroid Build Coastguard Worker 	int len = 0;
175*49cdfc7eSAndroid Build Coastguard Worker 	int ttype_result = TTYPE_RESULT(ttype);
176*49cdfc7eSAndroid Build Coastguard Worker 
177*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype_result == TDEBUG) {
178*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: TDEBUG is not supported\n", __func__, __LINE__);
179*49cdfc7eSAndroid Build Coastguard Worker 		abort();
180*49cdfc7eSAndroid Build Coastguard Worker 	}
181*49cdfc7eSAndroid Build Coastguard Worker 
182*49cdfc7eSAndroid Build Coastguard Worker 	if (file && (ttype_result != TPASS && ttype_result != TINFO))
183*49cdfc7eSAndroid Build Coastguard Worker 		len = sprintf(tmesg, "%s:%d: ", file, lineno);
184*49cdfc7eSAndroid Build Coastguard Worker 	EXPAND_VAR_ARGS(tmesg + len, arg_fmt, USERMESG - len);
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker 	/*
187*49cdfc7eSAndroid Build Coastguard Worker 	 * Save the test result type by ORing ttype into the current exit
188*49cdfc7eSAndroid Build Coastguard Worker 	 * value (used by tst_exit()).
189*49cdfc7eSAndroid Build Coastguard Worker 	 */
190*49cdfc7eSAndroid Build Coastguard Worker 	T_exitval |= ttype_result;
191*49cdfc7eSAndroid Build Coastguard Worker 
192*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype_result == TPASS)
193*49cdfc7eSAndroid Build Coastguard Worker 		passed_cnt++;
194*49cdfc7eSAndroid Build Coastguard Worker 
195*49cdfc7eSAndroid Build Coastguard Worker 	check_env();
196*49cdfc7eSAndroid Build Coastguard Worker 
197*49cdfc7eSAndroid Build Coastguard Worker 	/*
198*49cdfc7eSAndroid Build Coastguard Worker 	 * Set the test case number and print the results, depending on the
199*49cdfc7eSAndroid Build Coastguard Worker 	 * display type.
200*49cdfc7eSAndroid Build Coastguard Worker 	 */
201*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype_result == TWARN || ttype_result == TINFO) {
202*49cdfc7eSAndroid Build Coastguard Worker 		tst_print(TCID, 0, ttype, tmesg);
203*49cdfc7eSAndroid Build Coastguard Worker 	} else {
204*49cdfc7eSAndroid Build Coastguard Worker 		if (tst_count < 0)
205*49cdfc7eSAndroid Build Coastguard Worker 			tst_print(TCID, 0, TWARN,
206*49cdfc7eSAndroid Build Coastguard Worker 				  "tst_res(): tst_count < 0 is not valid");
207*49cdfc7eSAndroid Build Coastguard Worker 
208*49cdfc7eSAndroid Build Coastguard Worker 		/*
209*49cdfc7eSAndroid Build Coastguard Worker 		 * Process each display type.
210*49cdfc7eSAndroid Build Coastguard Worker 		 */
211*49cdfc7eSAndroid Build Coastguard Worker 		switch (T_mode) {
212*49cdfc7eSAndroid Build Coastguard Worker 		case DISCARD:
213*49cdfc7eSAndroid Build Coastguard Worker 			break;
214*49cdfc7eSAndroid Build Coastguard Worker 		case NOPASS:	/* filtered by tst_print() */
215*49cdfc7eSAndroid Build Coastguard Worker 			tst_condense(tst_count + 1, ttype, tmesg);
216*49cdfc7eSAndroid Build Coastguard Worker 			break;
217*49cdfc7eSAndroid Build Coastguard Worker 		default:	/* VERBOSE */
218*49cdfc7eSAndroid Build Coastguard Worker 			tst_print(TCID, tst_count + 1, ttype, tmesg);
219*49cdfc7eSAndroid Build Coastguard Worker 			break;
220*49cdfc7eSAndroid Build Coastguard Worker 		}
221*49cdfc7eSAndroid Build Coastguard Worker 
222*49cdfc7eSAndroid Build Coastguard Worker 		tst_count++;
223*49cdfc7eSAndroid Build Coastguard Worker 	}
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&tmutex);
226*49cdfc7eSAndroid Build Coastguard Worker }
227*49cdfc7eSAndroid Build Coastguard Worker 
tst_condense(int tnum,int ttype,const char * tmesg)228*49cdfc7eSAndroid Build Coastguard Worker static void tst_condense(int tnum, int ttype, const char *tmesg)
229*49cdfc7eSAndroid Build Coastguard Worker {
230*49cdfc7eSAndroid Build Coastguard Worker 	int ttype_result = TTYPE_RESULT(ttype);
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 	/*
233*49cdfc7eSAndroid Build Coastguard Worker 	 * If this result is the same as the previous result, return.
234*49cdfc7eSAndroid Build Coastguard Worker 	 */
235*49cdfc7eSAndroid Build Coastguard Worker 	if (Buffered == TRUE) {
236*49cdfc7eSAndroid Build Coastguard Worker 		if (strcmp(Last_tcid, TCID) == 0 && Last_type == ttype_result &&
237*49cdfc7eSAndroid Build Coastguard Worker 		    strcmp(Last_mesg, tmesg) == 0)
238*49cdfc7eSAndroid Build Coastguard Worker 			return;
239*49cdfc7eSAndroid Build Coastguard Worker 
240*49cdfc7eSAndroid Build Coastguard Worker 		/*
241*49cdfc7eSAndroid Build Coastguard Worker 		 * This result is different from the previous result.  First,
242*49cdfc7eSAndroid Build Coastguard Worker 		 * print the previous result.
243*49cdfc7eSAndroid Build Coastguard Worker 		 */
244*49cdfc7eSAndroid Build Coastguard Worker 		tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
245*49cdfc7eSAndroid Build Coastguard Worker 		free(Last_tcid);
246*49cdfc7eSAndroid Build Coastguard Worker 		free(Last_mesg);
247*49cdfc7eSAndroid Build Coastguard Worker 	}
248*49cdfc7eSAndroid Build Coastguard Worker 
249*49cdfc7eSAndroid Build Coastguard Worker 	/*
250*49cdfc7eSAndroid Build Coastguard Worker 	 * If a file was specified, print the current result since we have no
251*49cdfc7eSAndroid Build Coastguard Worker 	 * way of retaining the file contents for comparing with future
252*49cdfc7eSAndroid Build Coastguard Worker 	 * results.  Otherwise, buffer the current result info for next time.
253*49cdfc7eSAndroid Build Coastguard Worker 	 */
254*49cdfc7eSAndroid Build Coastguard Worker 	Last_tcid = malloc(strlen(TCID) + 1);
255*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(Last_tcid, TCID);
256*49cdfc7eSAndroid Build Coastguard Worker 	Last_num = tnum;
257*49cdfc7eSAndroid Build Coastguard Worker 	Last_type = ttype_result;
258*49cdfc7eSAndroid Build Coastguard Worker 	Last_mesg = malloc(strlen(tmesg) + 1);
259*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(Last_mesg, tmesg);
260*49cdfc7eSAndroid Build Coastguard Worker 	Buffered = TRUE;
261*49cdfc7eSAndroid Build Coastguard Worker }
262*49cdfc7eSAndroid Build Coastguard Worker 
tst_old_flush(void)263*49cdfc7eSAndroid Build Coastguard Worker void tst_old_flush(void)
264*49cdfc7eSAndroid Build Coastguard Worker {
265*49cdfc7eSAndroid Build Coastguard Worker 	NO_NEWLIB_ASSERT("Unknown", 0);
266*49cdfc7eSAndroid Build Coastguard Worker 
267*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&tmutex);
268*49cdfc7eSAndroid Build Coastguard Worker 
269*49cdfc7eSAndroid Build Coastguard Worker 	/*
270*49cdfc7eSAndroid Build Coastguard Worker 	 * Print out last line if in NOPASS mode.
271*49cdfc7eSAndroid Build Coastguard Worker 	 */
272*49cdfc7eSAndroid Build Coastguard Worker 	if (Buffered == TRUE && T_mode == NOPASS) {
273*49cdfc7eSAndroid Build Coastguard Worker 		tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
274*49cdfc7eSAndroid Build Coastguard Worker 		Buffered = FALSE;
275*49cdfc7eSAndroid Build Coastguard Worker 	}
276*49cdfc7eSAndroid Build Coastguard Worker 
277*49cdfc7eSAndroid Build Coastguard Worker 	fflush(stdout);
278*49cdfc7eSAndroid Build Coastguard Worker 
279*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&tmutex);
280*49cdfc7eSAndroid Build Coastguard Worker }
281*49cdfc7eSAndroid Build Coastguard Worker 
tst_print(const char * tcid,int tnum,int ttype,const char * tmesg)282*49cdfc7eSAndroid Build Coastguard Worker static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg)
283*49cdfc7eSAndroid Build Coastguard Worker {
284*49cdfc7eSAndroid Build Coastguard Worker 	int err = errno;
285*49cdfc7eSAndroid Build Coastguard Worker 	const char *type;
286*49cdfc7eSAndroid Build Coastguard Worker 	int ttype_result = TTYPE_RESULT(ttype);
287*49cdfc7eSAndroid Build Coastguard Worker 	char message[USERMESG];
288*49cdfc7eSAndroid Build Coastguard Worker 	size_t size = 0;
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker 	/*
291*49cdfc7eSAndroid Build Coastguard Worker 	 * Save the test result type by ORing ttype into the current exit value
292*49cdfc7eSAndroid Build Coastguard Worker 	 * (used by tst_exit()).  This is already done in tst_res(), but is
293*49cdfc7eSAndroid Build Coastguard Worker 	 * also done here to catch internal warnings.  For internal warnings,
294*49cdfc7eSAndroid Build Coastguard Worker 	 * tst_print() is called directly with a case of TWARN.
295*49cdfc7eSAndroid Build Coastguard Worker 	 */
296*49cdfc7eSAndroid Build Coastguard Worker 	T_exitval |= ttype_result;
297*49cdfc7eSAndroid Build Coastguard Worker 
298*49cdfc7eSAndroid Build Coastguard Worker 	/*
299*49cdfc7eSAndroid Build Coastguard Worker 	 * If output mode is DISCARD, or if the output mode is NOPASS and this
300*49cdfc7eSAndroid Build Coastguard Worker 	 * result is not one of FAIL, BROK, or WARN, just return.  This check
301*49cdfc7eSAndroid Build Coastguard Worker 	 * is necessary even though we check for DISCARD mode inside of
302*49cdfc7eSAndroid Build Coastguard Worker 	 * tst_res(), since occasionally we get to this point without going
303*49cdfc7eSAndroid Build Coastguard Worker 	 * through tst_res() (e.g. internal TWARN messages).
304*49cdfc7eSAndroid Build Coastguard Worker 	 */
305*49cdfc7eSAndroid Build Coastguard Worker 	if (T_mode == DISCARD || (T_mode == NOPASS && ttype_result != TFAIL &&
306*49cdfc7eSAndroid Build Coastguard Worker 				  ttype_result != TBROK
307*49cdfc7eSAndroid Build Coastguard Worker 				  && ttype_result != TWARN))
308*49cdfc7eSAndroid Build Coastguard Worker 		return;
309*49cdfc7eSAndroid Build Coastguard Worker 
310*49cdfc7eSAndroid Build Coastguard Worker 	/*
311*49cdfc7eSAndroid Build Coastguard Worker 	 * Build the result line and print it.
312*49cdfc7eSAndroid Build Coastguard Worker 	 */
313*49cdfc7eSAndroid Build Coastguard Worker 	type = strttype(ttype);
314*49cdfc7eSAndroid Build Coastguard Worker 
315*49cdfc7eSAndroid Build Coastguard Worker 	if (T_mode == VERBOSE) {
316*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
317*49cdfc7eSAndroid Build Coastguard Worker 				"%-8s %4d  ", tcid, tnum);
318*49cdfc7eSAndroid Build Coastguard Worker 	} else {
319*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
320*49cdfc7eSAndroid Build Coastguard Worker 				"%-8s %4d       ", tcid, tnum);
321*49cdfc7eSAndroid Build Coastguard Worker 	}
322*49cdfc7eSAndroid Build Coastguard Worker 
323*49cdfc7eSAndroid Build Coastguard Worker 	if (size >= sizeof(message)) {
324*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: line too long\n", __func__, __LINE__);
325*49cdfc7eSAndroid Build Coastguard Worker 		abort();
326*49cdfc7eSAndroid Build Coastguard Worker 	}
327*49cdfc7eSAndroid Build Coastguard Worker 
328*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_color_enabled(STDOUT_FILENO))
329*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
330*49cdfc7eSAndroid Build Coastguard Worker 		"%s%s%s  :  %s", tst_ttype2color(ttype), type, ANSI_COLOR_RESET, tmesg);
331*49cdfc7eSAndroid Build Coastguard Worker 	else
332*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
333*49cdfc7eSAndroid Build Coastguard Worker 		"%s  :  %s", type, tmesg);
334*49cdfc7eSAndroid Build Coastguard Worker 
335*49cdfc7eSAndroid Build Coastguard Worker 	if (size >= sizeof(message)) {
336*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: line too long\n", __func__, __LINE__);
337*49cdfc7eSAndroid Build Coastguard Worker 		abort();
338*49cdfc7eSAndroid Build Coastguard Worker 	}
339*49cdfc7eSAndroid Build Coastguard Worker 
340*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype & TERRNO) {
341*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
342*49cdfc7eSAndroid Build Coastguard Worker 				 ": errno=%s(%i): %s", tst_strerrno(err),
343*49cdfc7eSAndroid Build Coastguard Worker 				 err, strerror(err));
344*49cdfc7eSAndroid Build Coastguard Worker 	}
345*49cdfc7eSAndroid Build Coastguard Worker 
346*49cdfc7eSAndroid Build Coastguard Worker 	if (size >= sizeof(message)) {
347*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: line too long\n", __func__, __LINE__);
348*49cdfc7eSAndroid Build Coastguard Worker 		abort();
349*49cdfc7eSAndroid Build Coastguard Worker 	}
350*49cdfc7eSAndroid Build Coastguard Worker 
351*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype & TTERRNO) {
352*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
353*49cdfc7eSAndroid Build Coastguard Worker 				 ": TEST_ERRNO=%s(%i): %s",
354*49cdfc7eSAndroid Build Coastguard Worker 				 tst_strerrno(TEST_ERRNO), (int)TEST_ERRNO,
355*49cdfc7eSAndroid Build Coastguard Worker 				 strerror(TEST_ERRNO));
356*49cdfc7eSAndroid Build Coastguard Worker 	}
357*49cdfc7eSAndroid Build Coastguard Worker 
358*49cdfc7eSAndroid Build Coastguard Worker 	if (size >= sizeof(message)) {
359*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: line too long\n", __func__, __LINE__);
360*49cdfc7eSAndroid Build Coastguard Worker 		abort();
361*49cdfc7eSAndroid Build Coastguard Worker 	}
362*49cdfc7eSAndroid Build Coastguard Worker 
363*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype & TRERRNO) {
364*49cdfc7eSAndroid Build Coastguard Worker 		err = TEST_RETURN < 0 ? -(int)TEST_RETURN : (int)TEST_RETURN;
365*49cdfc7eSAndroid Build Coastguard Worker 		size += snprintf(message + size, sizeof(message) - size,
366*49cdfc7eSAndroid Build Coastguard Worker 				 ": TEST_RETURN=%s(%i): %s",
367*49cdfc7eSAndroid Build Coastguard Worker 				 tst_strerrno(err), err, strerror(err));
368*49cdfc7eSAndroid Build Coastguard Worker 	}
369*49cdfc7eSAndroid Build Coastguard Worker 
370*49cdfc7eSAndroid Build Coastguard Worker 	if (size + 1 >= sizeof(message)) {
371*49cdfc7eSAndroid Build Coastguard Worker 		printf("%s: %i: line too long\n", __func__, __LINE__);
372*49cdfc7eSAndroid Build Coastguard Worker 		abort();
373*49cdfc7eSAndroid Build Coastguard Worker 	}
374*49cdfc7eSAndroid Build Coastguard Worker 
375*49cdfc7eSAndroid Build Coastguard Worker 	message[size] = '\n';
376*49cdfc7eSAndroid Build Coastguard Worker 	message[size + 1] = '\0';
377*49cdfc7eSAndroid Build Coastguard Worker 
378*49cdfc7eSAndroid Build Coastguard Worker 	fputs(message, stdout);
379*49cdfc7eSAndroid Build Coastguard Worker }
380*49cdfc7eSAndroid Build Coastguard Worker 
check_env(void)381*49cdfc7eSAndroid Build Coastguard Worker static void check_env(void)
382*49cdfc7eSAndroid Build Coastguard Worker {
383*49cdfc7eSAndroid Build Coastguard Worker 	static int first_time = 1;
384*49cdfc7eSAndroid Build Coastguard Worker 	char *value;
385*49cdfc7eSAndroid Build Coastguard Worker 
386*49cdfc7eSAndroid Build Coastguard Worker 	if (!first_time)
387*49cdfc7eSAndroid Build Coastguard Worker 		return;
388*49cdfc7eSAndroid Build Coastguard Worker 
389*49cdfc7eSAndroid Build Coastguard Worker 	first_time = 0;
390*49cdfc7eSAndroid Build Coastguard Worker 
391*49cdfc7eSAndroid Build Coastguard Worker 	/* BTOUTPUT not defined, use default */
392*49cdfc7eSAndroid Build Coastguard Worker 	if ((value = getenv(TOUTPUT)) == NULL) {
393*49cdfc7eSAndroid Build Coastguard Worker 		T_mode = VERBOSE;
394*49cdfc7eSAndroid Build Coastguard Worker 		return;
395*49cdfc7eSAndroid Build Coastguard Worker 	}
396*49cdfc7eSAndroid Build Coastguard Worker 
397*49cdfc7eSAndroid Build Coastguard Worker 	if (strcmp(value, TOUT_NOPASS_S) == 0) {
398*49cdfc7eSAndroid Build Coastguard Worker 		T_mode = NOPASS;
399*49cdfc7eSAndroid Build Coastguard Worker 		return;
400*49cdfc7eSAndroid Build Coastguard Worker 	}
401*49cdfc7eSAndroid Build Coastguard Worker 
402*49cdfc7eSAndroid Build Coastguard Worker 	if (strcmp(value, TOUT_DISCARD_S) == 0) {
403*49cdfc7eSAndroid Build Coastguard Worker 		T_mode = DISCARD;
404*49cdfc7eSAndroid Build Coastguard Worker 		return;
405*49cdfc7eSAndroid Build Coastguard Worker 	}
406*49cdfc7eSAndroid Build Coastguard Worker 
407*49cdfc7eSAndroid Build Coastguard Worker 	T_mode = VERBOSE;
408*49cdfc7eSAndroid Build Coastguard Worker 	return;
409*49cdfc7eSAndroid Build Coastguard Worker }
410*49cdfc7eSAndroid Build Coastguard Worker 
tst_exit(void)411*49cdfc7eSAndroid Build Coastguard Worker void tst_exit(void)
412*49cdfc7eSAndroid Build Coastguard Worker {
413*49cdfc7eSAndroid Build Coastguard Worker 	NO_NEWLIB_ASSERT("Unknown", 0);
414*49cdfc7eSAndroid Build Coastguard Worker 
415*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&tmutex);
416*49cdfc7eSAndroid Build Coastguard Worker 
417*49cdfc7eSAndroid Build Coastguard Worker 	tst_old_flush();
418*49cdfc7eSAndroid Build Coastguard Worker 
419*49cdfc7eSAndroid Build Coastguard Worker 	T_exitval &= ~TINFO;
420*49cdfc7eSAndroid Build Coastguard Worker 
421*49cdfc7eSAndroid Build Coastguard Worker 	if (T_exitval == TCONF && passed_cnt)
422*49cdfc7eSAndroid Build Coastguard Worker 		T_exitval &= ~TCONF;
423*49cdfc7eSAndroid Build Coastguard Worker 
424*49cdfc7eSAndroid Build Coastguard Worker 	exit(T_exitval);
425*49cdfc7eSAndroid Build Coastguard Worker }
426*49cdfc7eSAndroid Build Coastguard Worker 
tst_fork(void)427*49cdfc7eSAndroid Build Coastguard Worker pid_t tst_fork(void)
428*49cdfc7eSAndroid Build Coastguard Worker {
429*49cdfc7eSAndroid Build Coastguard Worker 	pid_t child;
430*49cdfc7eSAndroid Build Coastguard Worker 
431*49cdfc7eSAndroid Build Coastguard Worker 	NO_NEWLIB_ASSERT("Unknown", 0);
432*49cdfc7eSAndroid Build Coastguard Worker 
433*49cdfc7eSAndroid Build Coastguard Worker 	tst_old_flush();
434*49cdfc7eSAndroid Build Coastguard Worker 
435*49cdfc7eSAndroid Build Coastguard Worker 	child = fork();
436*49cdfc7eSAndroid Build Coastguard Worker 	if (child == 0)
437*49cdfc7eSAndroid Build Coastguard Worker 		T_exitval = 0;
438*49cdfc7eSAndroid Build Coastguard Worker 
439*49cdfc7eSAndroid Build Coastguard Worker 	return child;
440*49cdfc7eSAndroid Build Coastguard Worker }
441*49cdfc7eSAndroid Build Coastguard Worker 
tst_record_childstatus(void (* cleanup)(void),pid_t child)442*49cdfc7eSAndroid Build Coastguard Worker void tst_record_childstatus(void (*cleanup)(void), pid_t child)
443*49cdfc7eSAndroid Build Coastguard Worker {
444*49cdfc7eSAndroid Build Coastguard Worker 	int status, ttype_result;
445*49cdfc7eSAndroid Build Coastguard Worker 
446*49cdfc7eSAndroid Build Coastguard Worker 	NO_NEWLIB_ASSERT("Unknown", 0);
447*49cdfc7eSAndroid Build Coastguard Worker 
448*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_WAITPID(cleanup, child, &status, 0);
449*49cdfc7eSAndroid Build Coastguard Worker 
450*49cdfc7eSAndroid Build Coastguard Worker 	if (WIFEXITED(status)) {
451*49cdfc7eSAndroid Build Coastguard Worker 		ttype_result = WEXITSTATUS(status);
452*49cdfc7eSAndroid Build Coastguard Worker 		ttype_result = TTYPE_RESULT(ttype_result);
453*49cdfc7eSAndroid Build Coastguard Worker 		T_exitval |= ttype_result;
454*49cdfc7eSAndroid Build Coastguard Worker 
455*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype_result == TPASS)
456*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Child process returned TPASS");
457*49cdfc7eSAndroid Build Coastguard Worker 
458*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype_result & TFAIL)
459*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Child process returned TFAIL");
460*49cdfc7eSAndroid Build Coastguard Worker 
461*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype_result & TBROK)
462*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Child process returned TBROK");
463*49cdfc7eSAndroid Build Coastguard Worker 
464*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype_result & TCONF)
465*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Child process returned TCONF");
466*49cdfc7eSAndroid Build Coastguard Worker 
467*49cdfc7eSAndroid Build Coastguard Worker 	} else {
468*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "child process(%d) killed by "
469*49cdfc7eSAndroid Build Coastguard Worker 			 "unexpected signal %s(%d)", child,
470*49cdfc7eSAndroid Build Coastguard Worker 			 tst_strsig(WTERMSIG(status)), WTERMSIG(status));
471*49cdfc7eSAndroid Build Coastguard Worker 	}
472*49cdfc7eSAndroid Build Coastguard Worker }
473*49cdfc7eSAndroid Build Coastguard Worker 
474*49cdfc7eSAndroid Build Coastguard Worker /*
475*49cdfc7eSAndroid Build Coastguard Worker  * Make tst_brk reentrant so that one can call the SAFE_* macros from within
476*49cdfc7eSAndroid Build Coastguard Worker  * user-defined cleanup functions.
477*49cdfc7eSAndroid Build Coastguard Worker  */
478*49cdfc7eSAndroid Build Coastguard Worker static int tst_brk_entered = 0;
479*49cdfc7eSAndroid Build Coastguard Worker 
tst_brk__(const char * file,const int lineno,int ttype,void (* func)(void),const char * arg_fmt,...)480*49cdfc7eSAndroid Build Coastguard Worker static void tst_brk__(const char *file, const int lineno, int ttype,
481*49cdfc7eSAndroid Build Coastguard Worker                       void (*func)(void), const char *arg_fmt, ...)
482*49cdfc7eSAndroid Build Coastguard Worker {
483*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&tmutex);
484*49cdfc7eSAndroid Build Coastguard Worker 
485*49cdfc7eSAndroid Build Coastguard Worker 	char tmesg[USERMESG];
486*49cdfc7eSAndroid Build Coastguard Worker 	int ttype_result = TTYPE_RESULT(ttype);
487*49cdfc7eSAndroid Build Coastguard Worker 
488*49cdfc7eSAndroid Build Coastguard Worker 	EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
489*49cdfc7eSAndroid Build Coastguard Worker 
490*49cdfc7eSAndroid Build Coastguard Worker 	/*
491*49cdfc7eSAndroid Build Coastguard Worker 	 * Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
492*49cdfc7eSAndroid Build Coastguard Worker 	 */
493*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype_result != TFAIL && ttype_result != TBROK &&
494*49cdfc7eSAndroid Build Coastguard Worker 	    ttype_result != TCONF) {
495*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(Warn_mesg, "%s: Invalid Type: %d. Using TBROK",
496*49cdfc7eSAndroid Build Coastguard Worker 			__func__, ttype_result);
497*49cdfc7eSAndroid Build Coastguard Worker 		tst_print(TCID, 0, TWARN, Warn_mesg);
498*49cdfc7eSAndroid Build Coastguard Worker 		/* Keep TERRNO, TTERRNO, etc. */
499*49cdfc7eSAndroid Build Coastguard Worker 		ttype = (ttype & ~ttype_result) | TBROK;
500*49cdfc7eSAndroid Build Coastguard Worker 	}
501*49cdfc7eSAndroid Build Coastguard Worker 
502*49cdfc7eSAndroid Build Coastguard Worker 	tst_res__(file, lineno, ttype, "%s", tmesg);
503*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_brk_entered == 0) {
504*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype_result == TCONF) {
505*49cdfc7eSAndroid Build Coastguard Worker 			tst_res__(file, lineno, ttype,
506*49cdfc7eSAndroid Build Coastguard Worker 				"Remaining cases not appropriate for "
507*49cdfc7eSAndroid Build Coastguard Worker 				"configuration");
508*49cdfc7eSAndroid Build Coastguard Worker 		} else if (ttype_result == TBROK) {
509*49cdfc7eSAndroid Build Coastguard Worker 			tst_res__(file, lineno, TBROK,
510*49cdfc7eSAndroid Build Coastguard Worker 				 "Remaining cases broken");
511*49cdfc7eSAndroid Build Coastguard Worker 		}
512*49cdfc7eSAndroid Build Coastguard Worker 	}
513*49cdfc7eSAndroid Build Coastguard Worker 
514*49cdfc7eSAndroid Build Coastguard Worker 	/*
515*49cdfc7eSAndroid Build Coastguard Worker 	 * If no cleanup function was specified, just return to the caller.
516*49cdfc7eSAndroid Build Coastguard Worker 	 * Otherwise call the specified function.
517*49cdfc7eSAndroid Build Coastguard Worker 	 */
518*49cdfc7eSAndroid Build Coastguard Worker 	if (func != NULL) {
519*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_entered++;
520*49cdfc7eSAndroid Build Coastguard Worker 		(*func) ();
521*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_entered--;
522*49cdfc7eSAndroid Build Coastguard Worker 	}
523*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_brk_entered == 0)
524*49cdfc7eSAndroid Build Coastguard Worker 		tst_exit();
525*49cdfc7eSAndroid Build Coastguard Worker 
526*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&tmutex);
527*49cdfc7eSAndroid Build Coastguard Worker }
528*49cdfc7eSAndroid Build Coastguard Worker 
tst_resm_(const char * file,const int lineno,int ttype,const char * arg_fmt,...)529*49cdfc7eSAndroid Build Coastguard Worker void tst_resm_(const char *file, const int lineno, int ttype,
530*49cdfc7eSAndroid Build Coastguard Worker 	const char *arg_fmt, ...)
531*49cdfc7eSAndroid Build Coastguard Worker {
532*49cdfc7eSAndroid Build Coastguard Worker 	char tmesg[USERMESG];
533*49cdfc7eSAndroid Build Coastguard Worker 
534*49cdfc7eSAndroid Build Coastguard Worker 	EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
535*49cdfc7eSAndroid Build Coastguard Worker 
536*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_test)
537*49cdfc7eSAndroid Build Coastguard Worker 		tst_res_(file, lineno, ttype, "%s", tmesg);
538*49cdfc7eSAndroid Build Coastguard Worker 	else
539*49cdfc7eSAndroid Build Coastguard Worker 		tst_res__(file, lineno, ttype, "%s", tmesg);
540*49cdfc7eSAndroid Build Coastguard Worker }
541*49cdfc7eSAndroid Build Coastguard Worker 
542*49cdfc7eSAndroid Build Coastguard Worker typedef void (*tst_res_func_t)(const char *file, const int lineno,
543*49cdfc7eSAndroid Build Coastguard Worker 		int ttype, const char *fmt, ...);
544*49cdfc7eSAndroid Build Coastguard Worker 
tst_resm_hexd_(const char * file,const int lineno,int ttype,const void * buf,size_t size,const char * arg_fmt,...)545*49cdfc7eSAndroid Build Coastguard Worker void tst_resm_hexd_(const char *file, const int lineno, int ttype,
546*49cdfc7eSAndroid Build Coastguard Worker 	const void *buf, size_t size, const char *arg_fmt, ...)
547*49cdfc7eSAndroid Build Coastguard Worker {
548*49cdfc7eSAndroid Build Coastguard Worker 	char tmesg[USERMESG];
549*49cdfc7eSAndroid Build Coastguard Worker 	static const size_t symb_num	= 2; /* xx */
550*49cdfc7eSAndroid Build Coastguard Worker 	static const size_t size_max	= 16;
551*49cdfc7eSAndroid Build Coastguard Worker 	size_t offset;
552*49cdfc7eSAndroid Build Coastguard Worker 	size_t i;
553*49cdfc7eSAndroid Build Coastguard Worker 	char *pmesg = tmesg;
554*49cdfc7eSAndroid Build Coastguard Worker 	tst_res_func_t res_func;
555*49cdfc7eSAndroid Build Coastguard Worker 
556*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_test)
557*49cdfc7eSAndroid Build Coastguard Worker 		res_func = tst_res_;
558*49cdfc7eSAndroid Build Coastguard Worker 	else
559*49cdfc7eSAndroid Build Coastguard Worker 		res_func = tst_res__;
560*49cdfc7eSAndroid Build Coastguard Worker 
561*49cdfc7eSAndroid Build Coastguard Worker 	EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
562*49cdfc7eSAndroid Build Coastguard Worker 	offset = strlen(tmesg);
563*49cdfc7eSAndroid Build Coastguard Worker 
564*49cdfc7eSAndroid Build Coastguard Worker 	if (size > size_max || size == 0 ||
565*49cdfc7eSAndroid Build Coastguard Worker 		(offset + size * (symb_num + 1)) >= USERMESG)
566*49cdfc7eSAndroid Build Coastguard Worker 		res_func(file, lineno, ttype, "%s", tmesg);
567*49cdfc7eSAndroid Build Coastguard Worker 	else
568*49cdfc7eSAndroid Build Coastguard Worker 		pmesg += offset;
569*49cdfc7eSAndroid Build Coastguard Worker 
570*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < size; ++i) {
571*49cdfc7eSAndroid Build Coastguard Worker 		/* add space before byte except first one */
572*49cdfc7eSAndroid Build Coastguard Worker 		if (pmesg != tmesg)
573*49cdfc7eSAndroid Build Coastguard Worker 			*(pmesg++) = ' ';
574*49cdfc7eSAndroid Build Coastguard Worker 
575*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(pmesg, "%02x", ((unsigned char *)buf)[i]);
576*49cdfc7eSAndroid Build Coastguard Worker 		pmesg += symb_num;
577*49cdfc7eSAndroid Build Coastguard Worker 		if ((i + 1) % size_max == 0 || i + 1 == size) {
578*49cdfc7eSAndroid Build Coastguard Worker 			res_func(file, lineno, ttype, "%s", tmesg);
579*49cdfc7eSAndroid Build Coastguard Worker 			pmesg = tmesg;
580*49cdfc7eSAndroid Build Coastguard Worker 		}
581*49cdfc7eSAndroid Build Coastguard Worker 	}
582*49cdfc7eSAndroid Build Coastguard Worker }
583*49cdfc7eSAndroid Build Coastguard Worker 
tst_brkm__(const char * file,const int lineno,int ttype,void (* func)(void),const char * arg_fmt,...)584*49cdfc7eSAndroid Build Coastguard Worker void tst_brkm__(const char *file, const int lineno, int ttype,
585*49cdfc7eSAndroid Build Coastguard Worker 	void (*func)(void), const char *arg_fmt, ...)
586*49cdfc7eSAndroid Build Coastguard Worker {
587*49cdfc7eSAndroid Build Coastguard Worker 	char tmesg[USERMESG];
588*49cdfc7eSAndroid Build Coastguard Worker 
589*49cdfc7eSAndroid Build Coastguard Worker 	EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
590*49cdfc7eSAndroid Build Coastguard Worker 
591*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_test) {
592*49cdfc7eSAndroid Build Coastguard Worker 		if (func) {
593*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk_(file, lineno, TBROK,
594*49cdfc7eSAndroid Build Coastguard Worker 			         "Non-NULL cleanup in newlib!");
595*49cdfc7eSAndroid Build Coastguard Worker 		}
596*49cdfc7eSAndroid Build Coastguard Worker 
597*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_(file, lineno, ttype, "%s", tmesg);
598*49cdfc7eSAndroid Build Coastguard Worker 	}
599*49cdfc7eSAndroid Build Coastguard Worker 
600*49cdfc7eSAndroid Build Coastguard Worker 	tst_brk__(file, lineno, ttype, func, "%s", tmesg);
601*49cdfc7eSAndroid Build Coastguard Worker 
602*49cdfc7eSAndroid Build Coastguard Worker 	/* Shouldn't be reached, but fixes build time warnings about noreturn. */
603*49cdfc7eSAndroid Build Coastguard Worker 	abort();
604*49cdfc7eSAndroid Build Coastguard Worker }
605*49cdfc7eSAndroid Build Coastguard Worker 
tst_require_root(void)606*49cdfc7eSAndroid Build Coastguard Worker void tst_require_root(void)
607*49cdfc7eSAndroid Build Coastguard Worker {
608*49cdfc7eSAndroid Build Coastguard Worker 	NO_NEWLIB_ASSERT("Unknown", 0);
609*49cdfc7eSAndroid Build Coastguard Worker 
610*49cdfc7eSAndroid Build Coastguard Worker 	if (geteuid() != 0)
611*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TCONF, NULL, "Test needs to be run as root");
612*49cdfc7eSAndroid Build Coastguard Worker }
613