blob: 261dec0fbba89d0781053d9ec52a9be7efd4bb98 [file] [log] [blame]
alaffincc2e5552000-07-27 17:13:18 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
Cyril Hrubis3e60f622016-02-03 18:25:11 +01003 * AUTHOR : Kent Rogers (from Dave Fenner's original)
4 * CO-PILOT : Rich Logan
5 * DATE STARTED : 05/01/90 (rewritten 1/96)
6 * Copyright (c) 2009-2016 Cyril Hrubis <chrubis@suse.cz>
subrata_modak88c166c2009-06-09 16:01:20 +00007 *
alaffincc2e5552000-07-27 17:13:18 +00008 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
vapier45a8ba02009-07-20 10:59:32 +000011 *
alaffincc2e5552000-07-27 17:13:18 +000012 * This program is distributed in the hope that it would be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
vapier45a8ba02009-07-20 10:59:32 +000015 *
alaffincc2e5552000-07-27 17:13:18 +000016 * Further, this software is distributed without any warranty that it is
17 * free of the rightful claim of any third person regarding infringement
18 * or the like. Any license provided herein, whether implied or
19 * otherwise, applies only to this software file. Patent licenses, if
20 * any, provided herein do not apply to combinations of this program with
21 * other software, or any other product whatsoever.
vapier45a8ba02009-07-20 10:59:32 +000022 *
alaffincc2e5552000-07-27 17:13:18 +000023 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080024 * with this program; if not, write the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
vapier45a8ba02009-07-20 10:59:32 +000026 *
alaffincc2e5552000-07-27 17:13:18 +000027 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
28 * Mountain View, CA 94043, or:
vapier45a8ba02009-07-20 10:59:32 +000029 *
30 * http://www.sgi.com
31 *
32 * For further information regarding this notice, see:
33 *
alaffincc2e5552000-07-27 17:13:18 +000034 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
35 */
36
Cyril Hrubis3e60f622016-02-03 18:25:11 +010037#define _GNU_SOURCE
Mike Frysinger55d8ae52014-02-13 04:11:45 -050038
Alexey Kodanev89293b22014-02-18 17:53:36 +040039#include <pthread.h>
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080040#include <assert.h>
alaffincc2e5552000-07-27 17:13:18 +000041#include <errno.h>
subrata_modak88c166c2009-06-09 16:01:20 +000042#include <stdio.h>
43#include <stdlib.h>
44#include <stdarg.h>
Garrett Cooperd3e6e8f2010-12-13 02:55:35 -080045#include <string.h>
subrata_modak88c166c2009-06-09 16:01:20 +000046#include <unistd.h>
Xiaoguang Wang8c1e0b32014-07-28 19:51:39 +080047#include <sys/types.h>
48#include <sys/wait.h>
49
subrata_modak88c166c2009-06-09 16:01:20 +000050#include "test.h"
vapier9799ea12009-07-20 02:42:32 +000051#include "usctest.h"
Cyril Hrubis06f9fe42013-06-26 14:55:48 +020052#include "ltp_priv.h"
alaffincc2e5552000-07-27 17:13:18 +000053
Cyril Hrubisfc416612013-08-05 14:06:45 +020054long TEST_RETURN;
55int TEST_ERRNO;
Cyril Hrubisfc416612013-08-05 14:06:45 +020056
Cyril Hrubis3e60f622016-02-03 18:25:11 +010057#define VERBOSE 1
alaffincc2e5552000-07-27 17:13:18 +000058#define NOPASS 3
59#define DISCARD 4
60
Wanlong Gao354ebb42012-12-07 10:10:04 +080061#define MAXMESG 80 /* max length of internal messages */
62#define USERMESG 2048 /* max length of user message */
alaffincc2e5552000-07-27 17:13:18 +000063#define TRUE 1
64#define FALSE 0
65
66/*
67 * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result
68 * message into the specified string.
Garrett Cooper41176c32010-12-20 22:59:45 -080069 *
70 * NOTE (garrcoop): arg_fmt _must_ be the last element in each function
71 * argument list that employs this.
alaffincc2e5552000-07-27 17:13:18 +000072 */
Garrett Cooper41176c32010-12-20 22:59:45 -080073#define EXPAND_VAR_ARGS(buf, arg_fmt, buf_len) do {\
74 va_list ap; \
75 assert(arg_fmt != NULL); \
76 va_start(ap, arg_fmt); \
77 vsnprintf(buf, buf_len, arg_fmt, ap); \
78 va_end(ap); \
79 assert(strlen(buf) > 0); \
80} while (0)
alaffincc2e5552000-07-27 17:13:18 +000081
Alexey Kodanev89293b22014-02-18 17:53:36 +040082static pthread_mutex_t tmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
83
subrata_modak88c166c2009-06-09 16:01:20 +000084static void check_env(void);
Mike Frysinger55d8ae52014-02-13 04:11:45 -050085static void tst_condense(int tnum, int ttype, const char *tmesg);
86static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg);
alaffincc2e5552000-07-27 17:13:18 +000087
Wanlong Gao354ebb42012-12-07 10:10:04 +080088static int T_exitval = 0; /* exit value used by tst_exit() */
89static int T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */
Cyril Hrubis3e60f622016-02-03 18:25:11 +010090 /* NOPASS, DISCARD */
alaffincc2e5552000-07-27 17:13:18 +000091
Wanlong Gao354ebb42012-12-07 10:10:04 +080092static char Warn_mesg[MAXMESG]; /* holds warning messages */
alaffincc2e5552000-07-27 17:13:18 +000093
94/*
95 * These are used for condensing output when NOT in verbose mode.
96 */
Wanlong Gao354ebb42012-12-07 10:10:04 +080097static int Buffered = FALSE; /* TRUE if condensed output is currently */
Cyril Hrubis3e60f622016-02-03 18:25:11 +010098 /* buffered (i.e. not yet printed) */
Wanlong Gao354ebb42012-12-07 10:10:04 +080099static char *Last_tcid; /* previous test case id */
100static int Last_num; /* previous test case number */
101static int Last_type; /* previous test result type */
102static char *Last_mesg; /* previous test result message */
alaffincc2e5552000-07-27 17:13:18 +0000103
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100104int tst_count = 0;
alaffincc2e5552000-07-27 17:13:18 +0000105
106/*
107 * These globals must be defined in the test.
108 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800109extern char *TCID; /* Test case identifier from the test source */
110extern int TST_TOTAL; /* Total number of test cases from the test */
Cyril Hrubis7b200262013-11-14 14:38:26 +0100111
alaffincc2e5552000-07-27 17:13:18 +0000112
vapier9799ea12009-07-20 02:42:32 +0000113struct pair {
114 const char *name;
115 int val;
116};
Wanlong Gao354ebb42012-12-07 10:10:04 +0800117
Cyril Hrubis7b200262013-11-14 14:38:26 +0100118#define PAIR(def) [def] = {.name = #def, .val = def},
Xiaoguang Wang1a6f68a2014-05-13 19:02:59 +0800119#define STRPAIR(key, value) [key] = {.name = value, .val = key},
Cyril Hrubis7b200262013-11-14 14:38:26 +0100120
Cyril Hrubisee75ce32014-02-05 14:05:06 +0100121#define PAIR_LOOKUP(pair_arr, idx) do { \
122 if (idx < 0 || (size_t)idx >= ARRAY_SIZE(pair_arr) || \
123 pair_arr[idx].name == NULL) \
124 return "???"; \
125 return pair_arr[idx].name; \
Cyril Hrubis7b200262013-11-14 14:38:26 +0100126} while (0)
vapier9799ea12009-07-20 02:42:32 +0000127
vapier9799ea12009-07-20 02:42:32 +0000128const char *strttype(int ttype)
129{
Mike Frysinger55d8ae52014-02-13 04:11:45 -0500130 static const struct pair ttype_pairs[] = {
vapier9799ea12009-07-20 02:42:32 +0000131 PAIR(TPASS)
Cyril Hrubis7b200262013-11-14 14:38:26 +0100132 PAIR(TFAIL)
133 PAIR(TBROK)
Cyril Hrubis7b200262013-11-14 14:38:26 +0100134 PAIR(TCONF)
135 PAIR(TWARN)
136 PAIR(TINFO)
vapier9799ea12009-07-20 02:42:32 +0000137 };
Cyril Hrubis7b200262013-11-14 14:38:26 +0100138
139 PAIR_LOOKUP(ttype_pairs, TTYPE_RESULT(ttype));
vapier9799ea12009-07-20 02:42:32 +0000140}
141
Cyril Hrubis7b200262013-11-14 14:38:26 +0100142#include "errnos.h"
Xiaoguang Wang1a6f68a2014-05-13 19:02:59 +0800143#include "signame.h"
144
Cyril Hrubis6bb766e2015-12-16 13:28:47 +0100145static void tst_res__(const char *file, const int lineno, int ttype,
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100146 const char *arg_fmt, ...)
alaffincc2e5552000-07-27 17:13:18 +0000147{
Alexey Kodanev89293b22014-02-18 17:53:36 +0400148 pthread_mutex_lock(&tmutex);
149
subrata_modak88c166c2009-06-09 16:01:20 +0000150 char tmesg[USERMESG];
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800151 int len = 0;
vapier9799ea12009-07-20 02:42:32 +0000152 int ttype_result = TTYPE_RESULT(ttype);
alaffincc2e5552000-07-27 17:13:18 +0000153
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800154 if (file && (ttype_result != TPASS && ttype_result != TINFO))
155 len = sprintf(tmesg, "%s:%d: ", file, lineno);
156 EXPAND_VAR_ARGS(tmesg + len, arg_fmt, USERMESG - len);
alaffincc2e5552000-07-27 17:13:18 +0000157
subrata_modak88c166c2009-06-09 16:01:20 +0000158 /*
159 * Save the test result type by ORing ttype into the current exit
160 * value (used by tst_exit()).
161 */
vapier9799ea12009-07-20 02:42:32 +0000162 T_exitval |= ttype_result;
alaffincc2e5552000-07-27 17:13:18 +0000163
subrata_modak88c166c2009-06-09 16:01:20 +0000164 check_env();
alaffincc2e5552000-07-27 17:13:18 +0000165
subrata_modak88c166c2009-06-09 16:01:20 +0000166 /*
167 * Set the test case number and print the results, depending on the
168 * display type.
169 */
vapier9799ea12009-07-20 02:42:32 +0000170 if (ttype_result == TWARN || ttype_result == TINFO) {
Garrett Cooper5b875442010-12-13 20:49:15 -0800171 tst_print(TCID, 0, ttype, tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000172 } else {
Caspar Zhangd59a6592013-03-07 14:59:12 +0800173 if (tst_count < 0)
Garrett Cooper5b875442010-12-13 20:49:15 -0800174 tst_print(TCID, 0, TWARN,
Caspar Zhangd59a6592013-03-07 14:59:12 +0800175 "tst_res(): tst_count < 0 is not valid");
alaffincc2e5552000-07-27 17:13:18 +0000176
subrata_modak88c166c2009-06-09 16:01:20 +0000177 /*
178 * Process each display type.
179 */
180 switch (T_mode) {
Garrett Cooper8798ebf2010-12-13 20:27:37 -0800181 case DISCARD:
subrata_modak88c166c2009-06-09 16:01:20 +0000182 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800183 case NOPASS: /* filtered by tst_print() */
Caspar Zhangd59a6592013-03-07 14:59:12 +0800184 tst_condense(tst_count + 1, ttype, tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000185 break;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800186 default: /* VERBOSE */
Caspar Zhangd59a6592013-03-07 14:59:12 +0800187 tst_print(TCID, tst_count + 1, ttype, tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000188 break;
189 }
alaffincc2e5552000-07-27 17:13:18 +0000190
Caspar Zhangd59a6592013-03-07 14:59:12 +0800191 tst_count++;
subrata_modak88c166c2009-06-09 16:01:20 +0000192 }
alaffincc2e5552000-07-27 17:13:18 +0000193
Alexey Kodanev89293b22014-02-18 17:53:36 +0400194 pthread_mutex_unlock(&tmutex);
subrata_modak88c166c2009-06-09 16:01:20 +0000195}
alaffincc2e5552000-07-27 17:13:18 +0000196
Mike Frysinger55d8ae52014-02-13 04:11:45 -0500197static void tst_condense(int tnum, int ttype, const char *tmesg)
alaffincc2e5552000-07-27 17:13:18 +0000198{
vapier9799ea12009-07-20 02:42:32 +0000199 int ttype_result = TTYPE_RESULT(ttype);
alaffincc2e5552000-07-27 17:13:18 +0000200
subrata_modak88c166c2009-06-09 16:01:20 +0000201 /*
202 * If this result is the same as the previous result, return.
203 */
204 if (Buffered == TRUE) {
vapier9799ea12009-07-20 02:42:32 +0000205 if (strcmp(Last_tcid, TCID) == 0 && Last_type == ttype_result &&
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100206 strcmp(Last_mesg, tmesg) == 0)
subrata_modak88c166c2009-06-09 16:01:20 +0000207 return;
alaffincc2e5552000-07-27 17:13:18 +0000208
subrata_modak88c166c2009-06-09 16:01:20 +0000209 /*
210 * This result is different from the previous result. First,
211 * print the previous result.
212 */
Garrett Cooper5b875442010-12-13 20:49:15 -0800213 tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000214 free(Last_tcid);
215 free(Last_mesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000216 }
alaffincc2e5552000-07-27 17:13:18 +0000217
subrata_modak88c166c2009-06-09 16:01:20 +0000218 /*
219 * If a file was specified, print the current result since we have no
220 * way of retaining the file contents for comparing with future
221 * results. Otherwise, buffer the current result info for next time.
222 */
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100223 Last_tcid = malloc(strlen(TCID) + 1);
224 strcpy(Last_tcid, TCID);
225 Last_num = tnum;
226 Last_type = ttype_result;
227 Last_mesg = malloc(strlen(tmesg) + 1);
228 strcpy(Last_mesg, tmesg);
229 Buffered = TRUE;
subrata_modak88c166c2009-06-09 16:01:20 +0000230}
alaffincc2e5552000-07-27 17:13:18 +0000231
subrata_modak88c166c2009-06-09 16:01:20 +0000232void tst_flush(void)
alaffincc2e5552000-07-27 17:13:18 +0000233{
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100234 NO_NEWLIB_ASSERT("Unknown", 0);
235
Alexey Kodanev89293b22014-02-18 17:53:36 +0400236 pthread_mutex_lock(&tmutex);
237
subrata_modak88c166c2009-06-09 16:01:20 +0000238 /*
Garrett Cooper5b875442010-12-13 20:49:15 -0800239 * Print out last line if in NOPASS mode.
subrata_modak88c166c2009-06-09 16:01:20 +0000240 */
Garrett Cooper5b875442010-12-13 20:49:15 -0800241 if (Buffered == TRUE && T_mode == NOPASS) {
242 tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000243 Buffered = FALSE;
244 }
245
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100246 fflush(stdout);
Alexey Kodanev89293b22014-02-18 17:53:36 +0400247
248 pthread_mutex_unlock(&tmutex);
subrata_modak88c166c2009-06-09 16:01:20 +0000249}
alaffincc2e5552000-07-27 17:13:18 +0000250
Mike Frysinger55d8ae52014-02-13 04:11:45 -0500251static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg)
alaffincc2e5552000-07-27 17:13:18 +0000252{
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800253 int err = errno;
vapier9799ea12009-07-20 02:42:32 +0000254 const char *type;
255 int ttype_result = TTYPE_RESULT(ttype);
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100256 char message[USERMESG];
Cyril Hrubisee75ce32014-02-05 14:05:06 +0100257 size_t size;
alaffincc2e5552000-07-27 17:13:18 +0000258
subrata_modak88c166c2009-06-09 16:01:20 +0000259 /*
260 * Save the test result type by ORing ttype into the current exit value
261 * (used by tst_exit()). This is already done in tst_res(), but is
262 * also done here to catch internal warnings. For internal warnings,
263 * tst_print() is called directly with a case of TWARN.
264 */
vapier9799ea12009-07-20 02:42:32 +0000265 T_exitval |= ttype_result;
alaffincc2e5552000-07-27 17:13:18 +0000266
subrata_modak88c166c2009-06-09 16:01:20 +0000267 /*
268 * If output mode is DISCARD, or if the output mode is NOPASS and this
269 * result is not one of FAIL, BROK, or WARN, just return. This check
270 * is necessary even though we check for DISCARD mode inside of
271 * tst_res(), since occasionally we get to this point without going
272 * through tst_res() (e.g. internal TWARN messages).
273 */
vapier9799ea12009-07-20 02:42:32 +0000274 if (T_mode == DISCARD || (T_mode == NOPASS && ttype_result != TFAIL &&
Wanlong Gao354ebb42012-12-07 10:10:04 +0800275 ttype_result != TBROK
276 && ttype_result != TWARN))
subrata_modak88c166c2009-06-09 16:01:20 +0000277 return;
alaffincc2e5552000-07-27 17:13:18 +0000278
subrata_modak88c166c2009-06-09 16:01:20 +0000279 /*
subrata_modak88c166c2009-06-09 16:01:20 +0000280 * Build the result line and print it.
281 */
vapier9799ea12009-07-20 02:42:32 +0000282 type = strttype(ttype);
subrata_modak88c166c2009-06-09 16:01:20 +0000283 if (T_mode == VERBOSE) {
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100284 size = snprintf(message, sizeof(message),
Wanlong Gao354ebb42012-12-07 10:10:04 +0800285 "%-8s %4d %s : %s", tcid, tnum, type, tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000286 } else {
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100287 size = snprintf(message, sizeof(message),
Wanlong Gao354ebb42012-12-07 10:10:04 +0800288 "%-8s %4d %s : %s",
289 tcid, tnum, type, tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000290 }
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100291
292 if (size >= sizeof(message)) {
293 printf("%s: %i: line too long\n", __func__, __LINE__);
294 abort();
295 }
296
vapier9799ea12009-07-20 02:42:32 +0000297 if (ttype & TERRNO) {
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100298 size += snprintf(message + size, sizeof(message) - size,
Xiaoguang Wang1a6f68a2014-05-13 19:02:59 +0800299 ": errno=%s(%i): %s", tst_strerrno(err),
Wanlong Gao354ebb42012-12-07 10:10:04 +0800300 err, strerror(err));
vapier9799ea12009-07-20 02:42:32 +0000301 }
Chris Dearman37550cf2012-10-17 19:54:01 -0700302
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100303 if (size >= sizeof(message)) {
304 printf("%s: %i: line too long\n", __func__, __LINE__);
305 abort();
306 }
Chris Dearman37550cf2012-10-17 19:54:01 -0700307
yaberauneya7113a0c2009-12-01 08:57:20 +0000308 if (ttype & TTERRNO) {
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100309 size += snprintf(message + size, sizeof(message) - size,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800310 ": TEST_ERRNO=%s(%i): %s",
Xiaoguang Wang1a6f68a2014-05-13 19:02:59 +0800311 tst_strerrno(TEST_ERRNO), (int)TEST_ERRNO,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800312 strerror(TEST_ERRNO));
yaberauneya7113a0c2009-12-01 08:57:20 +0000313 }
Chris Dearman37550cf2012-10-17 19:54:01 -0700314
Jan Stancek927a15c2014-09-11 11:11:45 +0200315 if (size >= sizeof(message)) {
316 printf("%s: %i: line too long\n", __func__, __LINE__);
317 abort();
318 }
319
320 if (ttype & TRERRNO) {
321 size += snprintf(message + size, sizeof(message) - size,
322 ": TEST_RETURN=%s(%i): %s",
323 tst_strerrno(TEST_RETURN), (int)TEST_RETURN,
324 strerror(TEST_RETURN));
325 }
326
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100327 if (size + 1 >= sizeof(message)) {
328 printf("%s: %i: line too long\n", __func__, __LINE__);
329 abort();
330 }
Chris Dearman37550cf2012-10-17 19:54:01 -0700331
Wanlong Gao354ebb42012-12-07 10:10:04 +0800332 message[size] = '\n';
333 message[size + 1] = '\0';
Cyril Hrubisd2e9f842012-01-19 17:47:35 +0100334
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100335 fputs(message, stdout);
subrata_modak88c166c2009-06-09 16:01:20 +0000336}
alaffincc2e5552000-07-27 17:13:18 +0000337
subrata_modak88c166c2009-06-09 16:01:20 +0000338static void check_env(void)
alaffincc2e5552000-07-27 17:13:18 +0000339{
subrata_modak88c166c2009-06-09 16:01:20 +0000340 static int first_time = 1;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800341 char *value;
alaffincc2e5552000-07-27 17:13:18 +0000342
subrata_modak88c166c2009-06-09 16:01:20 +0000343 if (!first_time)
344 return;
alaffincc2e5552000-07-27 17:13:18 +0000345
subrata_modak88c166c2009-06-09 16:01:20 +0000346 first_time = 0;
alaffincc2e5552000-07-27 17:13:18 +0000347
Garrett Cooper60cd1672010-11-23 21:06:05 -0800348 /* BTOUTPUT not defined, use default */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800349 if ((value = getenv(TOUTPUT)) == NULL) {
subrata_modak88c166c2009-06-09 16:01:20 +0000350 T_mode = VERBOSE;
351 return;
352 }
alaffincc2e5552000-07-27 17:13:18 +0000353
subrata_modak88c166c2009-06-09 16:01:20 +0000354 if (strcmp(value, TOUT_NOPASS_S) == 0) {
355 T_mode = NOPASS;
356 return;
357 }
358
359 if (strcmp(value, TOUT_DISCARD_S) == 0) {
360 T_mode = DISCARD;
361 return;
362 }
363
subrata_modak88c166c2009-06-09 16:01:20 +0000364 T_mode = VERBOSE;
365 return;
366}
alaffincc2e5552000-07-27 17:13:18 +0000367
subrata_modak88c166c2009-06-09 16:01:20 +0000368void tst_exit(void)
alaffincc2e5552000-07-27 17:13:18 +0000369{
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100370 NO_NEWLIB_ASSERT("Unknown", 0);
371
Alexey Kodanev89293b22014-02-18 17:53:36 +0400372 pthread_mutex_lock(&tmutex);
373
subrata_modak88c166c2009-06-09 16:01:20 +0000374 tst_flush();
alaffincc2e5552000-07-27 17:13:18 +0000375
Xiaoguang Wangcdfe3372014-07-21 17:00:03 +0800376 exit(T_exitval & ~TINFO);
subrata_modak88c166c2009-06-09 16:01:20 +0000377}
alaffincc2e5552000-07-27 17:13:18 +0000378
Cyril Hrubisddd3b852014-02-03 17:10:04 +0100379pid_t tst_fork(void)
380{
Xiaoguang Wang8c1e0b32014-07-28 19:51:39 +0800381 pid_t child;
382
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100383 NO_NEWLIB_ASSERT("Unknown", 0);
384
Cyril Hrubisddd3b852014-02-03 17:10:04 +0100385 tst_flush();
Xiaoguang Wang8c1e0b32014-07-28 19:51:39 +0800386
387 child = fork();
388 if (child == 0)
389 T_exitval = 0;
390
391 return child;
392}
393
394void tst_record_childstatus(void (*cleanup)(void), pid_t child)
395{
396 int status, ttype_result;
397
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100398 NO_NEWLIB_ASSERT("Unknown", 0);
399
Xiaoguang Wang8c1e0b32014-07-28 19:51:39 +0800400 if (waitpid(child, &status, 0) < 0)
401 tst_brkm(TBROK | TERRNO, cleanup, "waitpid(%d) failed", child);
402
403 if (WIFEXITED(status)) {
404 ttype_result = WEXITSTATUS(status);
405 ttype_result = TTYPE_RESULT(ttype_result);
406 T_exitval |= ttype_result;
407
408 if (ttype_result == TPASS)
409 tst_resm(TINFO, "Child process returned TPASS");
410
411 if (ttype_result & TFAIL)
412 tst_resm(TINFO, "Child process returned TFAIL");
413
414 if (ttype_result & TBROK)
415 tst_resm(TINFO, "Child process returned TBROK");
416
417 if (ttype_result & TCONF)
418 tst_resm(TINFO, "Child process returned TCONF");
419
420 } else {
421 tst_brkm(TBROK, cleanup, "child process(%d) killed by "
422 "unexpected signal %s(%d)", child,
423 tst_strsig(WTERMSIG(status)), WTERMSIG(status));
424 }
Cyril Hrubisddd3b852014-02-03 17:10:04 +0100425}
426
Cyril Hrubis3f0510c2014-02-06 13:50:14 +0100427pid_t tst_vfork(void)
428{
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100429 NO_NEWLIB_ASSERT("Unknown", 0);
430
Cyril Hrubis3f0510c2014-02-06 13:50:14 +0100431 tst_flush();
432 return vfork();
433}
434
alaffincc2e5552000-07-27 17:13:18 +0000435/*
Garrett Cooper68d76e02010-12-20 05:49:48 -0800436 * Make tst_brk reentrant so that one can call the SAFE_* macros from within
437 * user-defined cleanup functions.
438 */
Garrett Cooper43891b72010-12-20 06:37:22 -0800439static int tst_brk_entered = 0;
Garrett Cooper68d76e02010-12-20 05:49:48 -0800440
Cyril Hrubisec2765c2016-01-07 12:12:34 +0100441static void tst_brk__(const char *file, const int lineno, int ttype,
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100442 void (*func)(void), const char *arg_fmt, ...)
alaffincc2e5552000-07-27 17:13:18 +0000443{
Alexey Kodanev89293b22014-02-18 17:53:36 +0400444 pthread_mutex_lock(&tmutex);
445
subrata_modak88c166c2009-06-09 16:01:20 +0000446 char tmesg[USERMESG];
vapier9799ea12009-07-20 02:42:32 +0000447 int ttype_result = TTYPE_RESULT(ttype);
alaffincc2e5552000-07-27 17:13:18 +0000448
subrata_modak3311a252009-10-13 13:59:29 +0000449 EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
alaffincc2e5552000-07-27 17:13:18 +0000450
subrata_modak88c166c2009-06-09 16:01:20 +0000451 /*
452 * Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
453 */
vapier9799ea12009-07-20 02:42:32 +0000454 if (ttype_result != TFAIL && ttype_result != TBROK &&
Xiaoguang Wangcdfe3372014-07-21 17:00:03 +0800455 ttype_result != TCONF) {
Garrett Coopereacf2a32010-12-16 16:04:04 -0800456 sprintf(Warn_mesg, "%s: Invalid Type: %d. Using TBROK",
457 __func__, ttype_result);
Garrett Cooper5b875442010-12-13 20:49:15 -0800458 tst_print(TCID, 0, TWARN, Warn_mesg);
Garrett Coopereacf2a32010-12-16 16:04:04 -0800459 /* Keep TERRNO, TTERRNO, etc. */
460 ttype = (ttype & ~ttype_result) | TBROK;
subrata_modak88c166c2009-06-09 16:01:20 +0000461 }
alaffincc2e5552000-07-27 17:13:18 +0000462
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100463 tst_res__(file, lineno, ttype, "%s", tmesg);
Garrett Cooper68d76e02010-12-20 05:49:48 -0800464 if (tst_brk_entered == 0) {
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800465 if (ttype_result == TCONF) {
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100466 tst_res__(file, lineno, ttype,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800467 "Remaining cases not appropriate for "
468 "configuration");
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800469 } else if (ttype_result == TBROK) {
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100470 tst_res__(file, lineno, TBROK,
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800471 "Remaining cases broken");
472 }
Garrett Cooper68d76e02010-12-20 05:49:48 -0800473 }
alaffincc2e5552000-07-27 17:13:18 +0000474
alaffincc2e5552000-07-27 17:13:18 +0000475 /*
476 * If no cleanup function was specified, just return to the caller.
Garrett Cooper9f2555e2010-12-13 23:55:22 -0800477 * Otherwise call the specified function.
alaffincc2e5552000-07-27 17:13:18 +0000478 */
Garrett Cooper43891b72010-12-20 06:37:22 -0800479 if (func != NULL) {
480 tst_brk_entered++;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800481 (*func) ();
Garrett Cooper43891b72010-12-20 06:37:22 -0800482 tst_brk_entered--;
Garrett Cooper6bfb01e2010-11-22 10:16:28 -0800483 }
Garrett Cooper43891b72010-12-20 06:37:22 -0800484 if (tst_brk_entered == 0)
485 tst_exit();
486
Alexey Kodanev89293b22014-02-18 17:53:36 +0400487 pthread_mutex_unlock(&tmutex);
subrata_modak88c166c2009-06-09 16:01:20 +0000488}
alaffincc2e5552000-07-27 17:13:18 +0000489
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800490void tst_resm_(const char *file, const int lineno, int ttype,
491 const char *arg_fmt, ...)
alaffincc2e5552000-07-27 17:13:18 +0000492{
subrata_modak88c166c2009-06-09 16:01:20 +0000493 char tmesg[USERMESG];
alaffincc2e5552000-07-27 17:13:18 +0000494
subrata_modak3311a252009-10-13 13:59:29 +0000495 EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
alaffincc2e5552000-07-27 17:13:18 +0000496
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100497 if (tst_test)
498 tst_res_(file, lineno, ttype, "%s", tmesg);
499 else
500 tst_res__(file, lineno, ttype, "%s", tmesg);
subrata_modak88c166c2009-06-09 16:01:20 +0000501}
alaffincc2e5552000-07-27 17:13:18 +0000502
Jan Stancekf72ca5b2016-10-06 13:34:39 +0200503typedef void (*tst_res_func_t)(const char *file, const int lineno,
504 int ttype, const char *fmt, ...);
505
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800506void tst_resm_hexd_(const char *file, const int lineno, int ttype,
507 const void *buf, size_t size, const char *arg_fmt, ...)
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400508{
509 char tmesg[USERMESG];
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400510 static const size_t symb_num = 2; /* xx */
511 static const size_t size_max = 16;
512 size_t offset = strlen(tmesg);
Jan Stancekf72ca5b2016-10-06 13:34:39 +0200513 size_t i;
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400514 char *pmesg = tmesg;
Jan Stancekf72ca5b2016-10-06 13:34:39 +0200515 tst_res_func_t res_func;
516
517 if (tst_test)
518 res_func = tst_res_;
519 else
520 res_func = tst_res__;
521
522 EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400523
524 if (size > size_max || size == 0 ||
525 (offset + size * (symb_num + 1)) >= USERMESG)
Jan Stancekf72ca5b2016-10-06 13:34:39 +0200526 res_func(file, lineno, ttype, "%s", tmesg);
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400527 else
528 pmesg += offset;
529
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400530 for (i = 0; i < size; ++i) {
531 /* add space before byte except first one */
532 if (pmesg != tmesg)
533 *(pmesg++) = ' ';
534
535 sprintf(pmesg, "%02x", ((unsigned char *)buf)[i]);
536 pmesg += symb_num;
537 if ((i + 1) % size_max == 0 || i + 1 == size) {
Jan Stancekf72ca5b2016-10-06 13:34:39 +0200538 res_func(file, lineno, ttype, "%s", tmesg);
Alexey Kodanev04a34ba2013-05-23 11:03:18 +0400539 pmesg = tmesg;
540 }
541 }
542}
543
Xiaoguang Wanga161c6f2014-07-21 17:00:04 +0800544void tst_brkm_(const char *file, const int lineno, int ttype,
545 void (*func)(void), const char *arg_fmt, ...)
alaffincc2e5552000-07-27 17:13:18 +0000546{
subrata_modak88c166c2009-06-09 16:01:20 +0000547 char tmesg[USERMESG];
alaffincc2e5552000-07-27 17:13:18 +0000548
subrata_modak3311a252009-10-13 13:59:29 +0000549 EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
alaffincc2e5552000-07-27 17:13:18 +0000550
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100551 if (tst_test) {
552 if (func) {
553 tst_brk_(file, lineno, TBROK,
554 "Non-NULL cleanup in newlib!");
555 }
556
557 tst_brk_(file, lineno, ttype, "%s", tmesg);
558 } else {
559 tst_brk__(file, lineno, ttype, func, "%s", tmesg);
560 }
561
Cyril Hrubis3e60f622016-02-03 18:25:11 +0100562 /* Shouldn't be reached, but fixes build time warnings about noreturn. */
Mike Frysinger9f42be12014-01-13 18:09:23 -0500563 abort();
subrata_modak88c166c2009-06-09 16:01:20 +0000564}
alaffincc2e5552000-07-27 17:13:18 +0000565
Cyril Hrubisd1e794d2015-07-30 23:52:51 +0200566void tst_require_root(void)
vapier640adf42008-05-06 15:47:54 +0000567{
Cyril Hrubisbbdb9f72016-03-16 15:53:57 +0100568 NO_NEWLIB_ASSERT("Unknown", 0);
569
subrata_modak88c166c2009-06-09 16:01:20 +0000570 if (geteuid() != 0)
Cyril Hrubisd1e794d2015-07-30 23:52:51 +0200571 tst_brkm(TCONF, NULL, "Test needs to be run as root");
vapier640adf42008-05-06 15:47:54 +0000572}