xref: /illumos-gate/usr/src/test/libc-tests/tests/err/err.c (revision 6353250f8fb7d9f5b595f795d9f446e438685e2b)
1621b6cf7SAndy Fiddaman /*
2621b6cf7SAndy Fiddaman  * This file and its contents are supplied under the terms of the
3621b6cf7SAndy Fiddaman  * Common Development and Distribution License ("CDDL"), version 1.0.
4621b6cf7SAndy Fiddaman  * You may only use this file in accordance with the terms of version
5621b6cf7SAndy Fiddaman  * 1.0 of the CDDL.
6621b6cf7SAndy Fiddaman  *
7621b6cf7SAndy Fiddaman  * A full copy of the text of the CDDL should have accompanied this
8621b6cf7SAndy Fiddaman  * source.  A copy of the CDDL is also available via the Internet at
9621b6cf7SAndy Fiddaman  * http://www.illumos.org/license/CDDL.
10621b6cf7SAndy Fiddaman  */
11621b6cf7SAndy Fiddaman 
12621b6cf7SAndy Fiddaman /*
13621b6cf7SAndy Fiddaman  * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
14621b6cf7SAndy Fiddaman  */
15621b6cf7SAndy Fiddaman 
16621b6cf7SAndy Fiddaman /*
17621b6cf7SAndy Fiddaman  * This file exercises the various err(3C)/warn(3C) functions and produces
18621b6cf7SAndy Fiddaman  * output that is checked by the corresponding err.ksh script.
19621b6cf7SAndy Fiddaman  */
20621b6cf7SAndy Fiddaman 
21621b6cf7SAndy Fiddaman #include <stdio.h>
22621b6cf7SAndy Fiddaman #include <stdlib.h>
23621b6cf7SAndy Fiddaman #include <stdbool.h>
24621b6cf7SAndy Fiddaman #include <errno.h>
25621b6cf7SAndy Fiddaman #include <err.h>
26621b6cf7SAndy Fiddaman #include <sys/debug.h>
27621b6cf7SAndy Fiddaman 
28621b6cf7SAndy Fiddaman static FILE *stream = stderr;
29621b6cf7SAndy Fiddaman 
30621b6cf7SAndy Fiddaman typedef enum variant {
31621b6cf7SAndy Fiddaman 	VARIANT_ = 0,	/* warn(), err() */
32621b6cf7SAndy Fiddaman 	VARIANT_C,	/* warnc(), errc() */
33621b6cf7SAndy Fiddaman 	VARIANT_X,	/* warnx(), errx() */
34621b6cf7SAndy Fiddaman 	VARIANT_V,	/* vwarn(), verr() */
35621b6cf7SAndy Fiddaman 	VARIANT_VC,	/* vwarnc(), verrc() */
36621b6cf7SAndy Fiddaman 	VARIANT_VX,	/* vwarnx(), verrx() */
37621b6cf7SAndy Fiddaman } variant_t;
38621b6cf7SAndy Fiddaman 
39621b6cf7SAndy Fiddaman void
usage(void)40621b6cf7SAndy Fiddaman usage(void)
41621b6cf7SAndy Fiddaman {
42621b6cf7SAndy Fiddaman 	(void) fprintf(stderr,
43621b6cf7SAndy Fiddaman 	    "usage: err [-e errno] [-x code] [-v variant]\n");
44621b6cf7SAndy Fiddaman 	exit(EXIT_FAILURE);
45621b6cf7SAndy Fiddaman }
46621b6cf7SAndy Fiddaman 
47621b6cf7SAndy Fiddaman void
callback_func(int code)48621b6cf7SAndy Fiddaman callback_func(int code)
49621b6cf7SAndy Fiddaman {
50621b6cf7SAndy Fiddaman 	(void) fprintf(stream, "CALLBACK %d\n", code);
51621b6cf7SAndy Fiddaman }
52621b6cf7SAndy Fiddaman 
53621b6cf7SAndy Fiddaman void
xtest(variant_t variant,int errcode,int exitcode,const char * fmt,...)54621b6cf7SAndy Fiddaman xtest(variant_t variant, int errcode, int exitcode, const char *fmt, ...)
55621b6cf7SAndy Fiddaman {
56621b6cf7SAndy Fiddaman 	va_list va;
57621b6cf7SAndy Fiddaman 
58621b6cf7SAndy Fiddaman 	va_start(va, fmt);
59621b6cf7SAndy Fiddaman 
60621b6cf7SAndy Fiddaman 	switch (variant) {
61621b6cf7SAndy Fiddaman 	case VARIANT_V:
62621b6cf7SAndy Fiddaman 		errno = errcode;
63621b6cf7SAndy Fiddaman 		if (exitcode != 0)
64621b6cf7SAndy Fiddaman 			verr(exitcode, fmt, va);
65621b6cf7SAndy Fiddaman 		else
66621b6cf7SAndy Fiddaman 			vwarn(fmt, va);
67621b6cf7SAndy Fiddaman 		break;
68621b6cf7SAndy Fiddaman 	case VARIANT_VC:
69621b6cf7SAndy Fiddaman 		errno = 0;
70621b6cf7SAndy Fiddaman 		if (exitcode != 0)
71621b6cf7SAndy Fiddaman 			verrc(exitcode, errcode, fmt, va);
72621b6cf7SAndy Fiddaman 		else
73621b6cf7SAndy Fiddaman 			vwarnc(errcode, fmt, va);
74621b6cf7SAndy Fiddaman 		break;
75621b6cf7SAndy Fiddaman 	case VARIANT_VX:
76621b6cf7SAndy Fiddaman 		if (exitcode != 0)
77621b6cf7SAndy Fiddaman 			verrx(exitcode, fmt, va);
78621b6cf7SAndy Fiddaman 		else
79621b6cf7SAndy Fiddaman 			vwarnx(fmt, va);
80621b6cf7SAndy Fiddaman 		break;
81621b6cf7SAndy Fiddaman 	default:
82621b6cf7SAndy Fiddaman 		errx(EXIT_FAILURE, "Unhandled variant in %s", __func__);
83621b6cf7SAndy Fiddaman 	}
84621b6cf7SAndy Fiddaman 
85621b6cf7SAndy Fiddaman 	va_end(va);
86621b6cf7SAndy Fiddaman }
87621b6cf7SAndy Fiddaman 
88621b6cf7SAndy Fiddaman int
main(int argc,char ** argv)89621b6cf7SAndy Fiddaman main(int argc, char **argv)
90621b6cf7SAndy Fiddaman {
91621b6cf7SAndy Fiddaman 	int errcode = 0;
92621b6cf7SAndy Fiddaman 	int exitcode = 0;
93621b6cf7SAndy Fiddaman 	variant_t variant = VARIANT_;
94621b6cf7SAndy Fiddaman 	const char *errstr;
95621b6cf7SAndy Fiddaman 	long long num;
96621b6cf7SAndy Fiddaman 	int ch;
97621b6cf7SAndy Fiddaman 
98621b6cf7SAndy Fiddaman 	/*
99621b6cf7SAndy Fiddaman 	 * -e	specify errno for the test
100621b6cf7SAndy Fiddaman 	 * -v	select variant to test
101621b6cf7SAndy Fiddaman 	 * -x	specify exit code for the test
102621b6cf7SAndy Fiddaman 	 */
103621b6cf7SAndy Fiddaman 	while ((ch = getopt(argc, argv, "e:v:x:")) != -1) {
104621b6cf7SAndy Fiddaman 		switch (ch) {
105621b6cf7SAndy Fiddaman 		case 'e':
106621b6cf7SAndy Fiddaman 			num = strtonum(optarg, 0, 127, &errstr);
107621b6cf7SAndy Fiddaman 			if (errstr != NULL)
108621b6cf7SAndy Fiddaman 				errx(EXIT_FAILURE, "-x: %s", errstr);
109621b6cf7SAndy Fiddaman 			errcode = (int)num;
110621b6cf7SAndy Fiddaman 			break;
111621b6cf7SAndy Fiddaman 		case 'v':
112621b6cf7SAndy Fiddaman 			num = strtonum(optarg, 0, VARIANT_VX, &errstr);
113621b6cf7SAndy Fiddaman 			if (errstr != NULL)
114621b6cf7SAndy Fiddaman 				errx(EXIT_FAILURE, "-v: %s", errstr);
115621b6cf7SAndy Fiddaman 			switch (num) {
116621b6cf7SAndy Fiddaman 			case VARIANT_:
117621b6cf7SAndy Fiddaman 				variant = VARIANT_;
118621b6cf7SAndy Fiddaman 				break;
119621b6cf7SAndy Fiddaman 			case VARIANT_C:
120621b6cf7SAndy Fiddaman 				variant = VARIANT_C;
121621b6cf7SAndy Fiddaman 				break;
122621b6cf7SAndy Fiddaman 			case VARIANT_X:
123621b6cf7SAndy Fiddaman 				variant = VARIANT_X;
124621b6cf7SAndy Fiddaman 				break;
125621b6cf7SAndy Fiddaman 			case VARIANT_V:
126621b6cf7SAndy Fiddaman 				variant = VARIANT_V;
127621b6cf7SAndy Fiddaman 				break;
128621b6cf7SAndy Fiddaman 			case VARIANT_VC:
129621b6cf7SAndy Fiddaman 				variant = VARIANT_VC;
130621b6cf7SAndy Fiddaman 				break;
131621b6cf7SAndy Fiddaman 			case VARIANT_VX:
132621b6cf7SAndy Fiddaman 				variant = VARIANT_VX;
133621b6cf7SAndy Fiddaman 				break;
134621b6cf7SAndy Fiddaman 			default:
135*6353250fSRobert Mustacchi 				errx(EXIT_FAILURE, "Unknown variant %lld", num);
136621b6cf7SAndy Fiddaman 			}
137621b6cf7SAndy Fiddaman 			break;
138621b6cf7SAndy Fiddaman 		case 'x':
139621b6cf7SAndy Fiddaman 			num = strtonum(optarg, 0, 127, &errstr);
140621b6cf7SAndy Fiddaman 			if (errstr != NULL)
141621b6cf7SAndy Fiddaman 				errx(EXIT_FAILURE, "-x: %s", errstr);
142621b6cf7SAndy Fiddaman 			exitcode = (int)num;
143621b6cf7SAndy Fiddaman 			break;
144621b6cf7SAndy Fiddaman 		default:
145621b6cf7SAndy Fiddaman 			usage();
146621b6cf7SAndy Fiddaman 			break;
147621b6cf7SAndy Fiddaman 		}
148621b6cf7SAndy Fiddaman 	}
149621b6cf7SAndy Fiddaman 
150621b6cf7SAndy Fiddaman 	argc -= optind;
151621b6cf7SAndy Fiddaman 	argv += optind;
152621b6cf7SAndy Fiddaman 
153621b6cf7SAndy Fiddaman 	if (argc > 0)
154621b6cf7SAndy Fiddaman 		errx(EXIT_FAILURE, "Unexpected argument '%s'.", argv[1]);
155621b6cf7SAndy Fiddaman 
156621b6cf7SAndy Fiddaman 	switch (variant) {
157621b6cf7SAndy Fiddaman 	case VARIANT_:
158621b6cf7SAndy Fiddaman 		errno = errcode;
159621b6cf7SAndy Fiddaman 		if (exitcode != 0)
160621b6cf7SAndy Fiddaman 			err(exitcode, "E/%d/%d", variant, exitcode);
161621b6cf7SAndy Fiddaman 		else
162621b6cf7SAndy Fiddaman 			warn("W/%d", variant);
163621b6cf7SAndy Fiddaman 		break;
164621b6cf7SAndy Fiddaman 	case VARIANT_C:
165621b6cf7SAndy Fiddaman 		errno = 0;
166621b6cf7SAndy Fiddaman 		if (exitcode != 0)
167621b6cf7SAndy Fiddaman 			errc(exitcode, errcode, "E/%d/%d", variant, exitcode);
168621b6cf7SAndy Fiddaman 		else
169621b6cf7SAndy Fiddaman 			warnc(errcode, "W/%d", variant);
170621b6cf7SAndy Fiddaman 		break;
171621b6cf7SAndy Fiddaman 	case VARIANT_X:
172621b6cf7SAndy Fiddaman 		if (exitcode != 0)
173621b6cf7SAndy Fiddaman 			errx(exitcode, "E/%d/%d", variant, exitcode);
174621b6cf7SAndy Fiddaman 		else
175621b6cf7SAndy Fiddaman 			warnx("W/%d", variant);
176621b6cf7SAndy Fiddaman 		break;
177621b6cf7SAndy Fiddaman 	case VARIANT_V:
178621b6cf7SAndy Fiddaman 	case VARIANT_VC:
179621b6cf7SAndy Fiddaman 	case VARIANT_VX:
180621b6cf7SAndy Fiddaman 		if (exitcode != 0) {
181621b6cf7SAndy Fiddaman 			xtest(variant, errcode, exitcode, "E/%d/%d", variant,
182621b6cf7SAndy Fiddaman 			    exitcode);
183621b6cf7SAndy Fiddaman 		} else {
184621b6cf7SAndy Fiddaman 			xtest(variant, errcode, exitcode, "W/%d", variant);
185621b6cf7SAndy Fiddaman 		}
186621b6cf7SAndy Fiddaman 		break;
187621b6cf7SAndy Fiddaman 	}
188621b6cf7SAndy Fiddaman 
189621b6cf7SAndy Fiddaman 	return (0);
190621b6cf7SAndy Fiddaman }
191