summaryrefslogtreecommitdiffstats
path: root/kernel/tests/include/old/test.h
blob: 604254eea61b7202a4503d02a63fef19c3be148c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 * Copyright (c) 2009-2013 Cyril Hrubis chrubis@suse.cz
 */

#ifndef __TEST_H__
#define __TEST_H__

#ifdef TST_TEST_H__
# error Newlib tst_test.h already included
#endif /* TST_TEST_H__ */

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "usctest.h"

#include "tst_common.h"
#include "old_safe_file_ops.h"
#include "old_checkpoint.h"
#include "tst_process_state.h"
#include "old_resource.h"
#include "tst_res_flags.h"
#include "tst_kvercmp.h"
#include "tst_fs.h"
#include "tst_pid.h"
#include "tst_cmd.h"
#include "tst_cpu.h"
#include "tst_clone.h"
#include "old_device.h"
#include "old_tmpdir.h"
#include "tst_minmax.h"
#include "tst_get_bad_addr.h"
#include "tst_path_has_mnt_flags.h"

/*
 * Ensure that NUMSIGS is defined.
 * It should be defined in signal.h or sys/signal.h on
 * UNICOS/mk and IRIX systems.   On UNICOS systems,
 * it is not defined, thus it is being set to UNICOS's NSIG.
 * Note:  IRIX's NSIG (signals are 1-(NSIG-1))
 *      is not same meaning as UNICOS/UMK's NSIG  (signals 1-NSIG)
 */
#ifndef NUMSIGS
#define NUMSIGS NSIG
#endif


/* defines for unexpected signal setup routine (set_usig.c) */
#define FORK    1		/* SIGCHLD is to be ignored */
#define NOFORK  0		/* SIGCHLD is to be caught */
#define DEF_HANDLER SIG_ERR	/* tells set_usig() to use default signal handler */

/*
 * The following defines are used to control tst_res and t_result reporting.
 */

#define TOUTPUT	   "TOUTPUT"		/* The name of the environment variable */
					/* that can be set to one of the following */
					/* strings to control tst_res output */
					/* If not set, TOUT_VERBOSE_S is assumed */

/*
 * fork() can't be used on uClinux systems, so use FORK_OR_VFORK instead,
 * which will run vfork() on uClinux.
 * mmap() doesn't support MAP_PRIVATE on uClinux systems, so use
 * MAP_PRIVATE_EXCEPT_UCLINUX instead, which will skip the option on uClinux.
 * If MAP_PRIVATE really is required, the test can not be run on uClinux.
 */
#ifdef UCLINUX
# define FORK_OR_VFORK			tst_vfork
# define MAP_PRIVATE_EXCEPT_UCLINUX	0
/* tst_old_flush() + vfork() */
pid_t tst_vfork(void);
#else
# define FORK_OR_VFORK			tst_fork
# define MAP_PRIVATE_EXCEPT_UCLINUX	MAP_PRIVATE
#endif

/*
 * Macro to use for making functions called only once in
 * multi-threaded tests such as init or cleanup function.
 * The first call to @name_fn function by any thread shall
 * call the @exec_fn. Subsequent calls shall not call @exec_fn.
 * *_fn functions must not take any arguments.
 */
#define TST_DECLARE_ONCE_FN(name_fn, exec_fn)				\
	void name_fn(void)						\
	{								\
		static pthread_once_t ltp_once = PTHREAD_ONCE_INIT;	\
		pthread_once(&ltp_once, exec_fn);			\
	}

/*
 * lib/forker.c
 */
extern int Forker_pids[];
extern int Forker_npids;

typedef struct {
	char *option;	/* Valid option string (one option only) like "a:"  */
	int  *flag;	/* Pointer to location to set true if option given  */
	char **arg;	/* Pointer to location to place argument, if needed */
} option_t;

/* lib/tst_parse_opts.c */
void tst_parse_opts(int argc, char *argv[], const option_t *user_optarg,
                    void (*user_help)(void));

/* lib/tst_res.c */
const char *strttype(int ttype);

void tst_resm_(const char *file, const int lineno, int ttype,
	const char *arg_fmt, ...)
	__attribute__ ((format (printf, 4, 5)));
#define tst_resm(ttype, arg_fmt, ...) \
	tst_resm_(__FILE__, __LINE__, (ttype), \
		  (arg_fmt), ##__VA_ARGS__)

void tst_resm_hexd_(const char *file, const int lineno, int ttype,
	const void *buf, size_t size, const char *arg_fmt, ...)
	__attribute__ ((format (printf, 6, 7)));
#define tst_resm_hexd(ttype, buf, size, arg_fmt, ...) \
	tst_resm_hexd_(__FILE__, __LINE__, (ttype), (buf), (size), \
		       (arg_fmt), ##__VA_ARGS__)

void tst_brkm_(const char *file, const int lineno, int ttype,
	void (*func)(void), const char *arg_fmt, ...)
	__attribute__ ((format (printf, 5, 6))) LTP_ATTRIBUTE_NORETURN;

#ifdef LTPLIB
# include "ltp_priv.h"
# define tst_brkm(flags, cleanup, fmt, ...) do { \
	if (tst_test) \
		tst_brk_(__FILE__, __LINE__, flags, fmt, ##__VA_ARGS__); \
	else \
		tst_brkm_(__FILE__, __LINE__, flags, cleanup, fmt, ##__VA_ARGS__); \
	} while (0)
#else
# define tst_brkm(flags, cleanup, fmt, ...) do { \
		tst_brkm_(__FILE__, __LINE__, flags, cleanup, fmt, ##__VA_ARGS__); \
	} while (0)
#endif

void tst_require_root(void);
void tst_exit(void) LTP_ATTRIBUTE_NORETURN;
void tst_old_flush(void);

/*
 * tst_old_flush() + fork
 * NOTE: tst_fork() will reset T_exitval to 0 for child process.
 */
pid_t tst_fork(void);

/* lib/tst_res.c */
/*
 * In case we need do real test work in child process parent process can use
 * tst_record_childstatus() to make child process's test results propagated to
 * parent process correctly.
 *
 * The child can use tst_resm(), tst_brkm() followed by the tst_exit() or
 * plain old exit() (with TPASS, TFAIL and TBROK).
 *
 * WARNING: Be wary that the child cleanup function passed to tst_brkm()
 *          must clean only resources the child has allocated. E.g. the
 *          child cleanup is different function from the parent cleanup.
 */
void tst_record_childstatus(void (*cleanup)(void), pid_t child);

extern int tst_count;

/* lib/tst_sig.c */
void tst_sig(int fork_flag, void (*handler)(), void (*cleanup)());

/* lib/self_exec.c */
void maybe_run_child(void (*child)(), const char *fmt, ...);
int self_exec(const char *argv0, const char *fmt, ...);

/* lib/tst_mkfs.c
 *
 * @dev: path to a device
 * @fs_type: filesystem type
 * @fs_opts: NULL or NULL terminated array of mkfs options
 * @extra_opt: extra mkfs option which is passed after the device name
 */
#define tst_mkfs(cleanup, dev, fs_type, fs_opts, extra_opts) \
	tst_mkfs_(__FILE__, __LINE__, cleanup, dev, fs_type, \
		  fs_opts, extra_opts)
void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void),
	       const char *dev, const char *fs_type,
	       const char *const fs_opts[], const char *const extra_opts[]);

/* lib/tst_res.c
 * tst_strsig converts signal's value to corresponding string.
 * tst_strerrno converts errno to corresponding string.
 */
const char *tst_strsig(int sig);
const char *tst_strerrno(int err);

#ifdef TST_USE_COMPAT16_SYSCALL
#define TCID_BIT_SUFFIX "_16"
#elif  TST_USE_NEWER64_SYSCALL
#define TCID_BIT_SUFFIX "_64"
#else
#define TCID_BIT_SUFFIX ""
#endif
#define TCID_DEFINE(ID) char *TCID = (#ID TCID_BIT_SUFFIX)

#endif	/* __TEST_H__ */