xref: /aosp_15_r20/external/ltp/lib/tst_sys_conf.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2018 Jan Stancek <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  */
5*49cdfc7eSAndroid Build Coastguard Worker 
6*49cdfc7eSAndroid Build Coastguard Worker #include <limits.h>
7*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
8*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
9*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
10*49cdfc7eSAndroid Build Coastguard Worker 
11*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
12*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
13*49cdfc7eSAndroid Build Coastguard Worker #include "tst_sys_conf.h"
14*49cdfc7eSAndroid Build Coastguard Worker 
15*49cdfc7eSAndroid Build Coastguard Worker struct tst_sys_conf {
16*49cdfc7eSAndroid Build Coastguard Worker 	char path[PATH_MAX];
17*49cdfc7eSAndroid Build Coastguard Worker 	char value[PATH_MAX];
18*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_sys_conf *next;
19*49cdfc7eSAndroid Build Coastguard Worker };
20*49cdfc7eSAndroid Build Coastguard Worker 
21*49cdfc7eSAndroid Build Coastguard Worker static struct tst_sys_conf *save_restore_data;
22*49cdfc7eSAndroid Build Coastguard Worker 
print_error(const int lineno,int info_only,const char * err,const char * path)23*49cdfc7eSAndroid Build Coastguard Worker static void print_error(const int lineno, int info_only, const char *err,
24*49cdfc7eSAndroid Build Coastguard Worker 	const char *path)
25*49cdfc7eSAndroid Build Coastguard Worker {
26*49cdfc7eSAndroid Build Coastguard Worker 	if (info_only)
27*49cdfc7eSAndroid Build Coastguard Worker 		tst_res_(__FILE__, lineno, TINFO | TERRNO, err, path);
28*49cdfc7eSAndroid Build Coastguard Worker 	else
29*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_(__FILE__, lineno, TBROK | TERRNO, err, path);
30*49cdfc7eSAndroid Build Coastguard Worker }
31*49cdfc7eSAndroid Build Coastguard Worker 
tst_sys_conf_dump(void)32*49cdfc7eSAndroid Build Coastguard Worker void tst_sys_conf_dump(void)
33*49cdfc7eSAndroid Build Coastguard Worker {
34*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_sys_conf *i;
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker 	for (i = save_restore_data; i; i = i->next)
37*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TINFO, "%s = %s", i->path, i->value);
38*49cdfc7eSAndroid Build Coastguard Worker }
39*49cdfc7eSAndroid Build Coastguard Worker 
tst_sys_conf_save_str(const char * path,const char * value)40*49cdfc7eSAndroid Build Coastguard Worker void tst_sys_conf_save_str(const char *path, const char *value)
41*49cdfc7eSAndroid Build Coastguard Worker {
42*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_sys_conf *n = SAFE_MALLOC(sizeof(*n));
43*49cdfc7eSAndroid Build Coastguard Worker 
44*49cdfc7eSAndroid Build Coastguard Worker 	strncpy(n->path, path, sizeof(n->path)-1);
45*49cdfc7eSAndroid Build Coastguard Worker 	strncpy(n->value, value, sizeof(n->value)-1);
46*49cdfc7eSAndroid Build Coastguard Worker 
47*49cdfc7eSAndroid Build Coastguard Worker 	n->path[sizeof(n->path) - 1] = 0;
48*49cdfc7eSAndroid Build Coastguard Worker 	n->value[sizeof(n->value) - 1] = 0;
49*49cdfc7eSAndroid Build Coastguard Worker 
50*49cdfc7eSAndroid Build Coastguard Worker 	n->next = save_restore_data;
51*49cdfc7eSAndroid Build Coastguard Worker 	save_restore_data = n;
52*49cdfc7eSAndroid Build Coastguard Worker }
53*49cdfc7eSAndroid Build Coastguard Worker 
tst_sys_conf_save(const struct tst_path_val * conf)54*49cdfc7eSAndroid Build Coastguard Worker int tst_sys_conf_save(const struct tst_path_val *conf)
55*49cdfc7eSAndroid Build Coastguard Worker {
56*49cdfc7eSAndroid Build Coastguard Worker 	char line[PATH_MAX];
57*49cdfc7eSAndroid Build Coastguard Worker 	int ttype, iret;
58*49cdfc7eSAndroid Build Coastguard Worker 	FILE *fp;
59*49cdfc7eSAndroid Build Coastguard Worker 	void *ret;
60*49cdfc7eSAndroid Build Coastguard Worker 
61*49cdfc7eSAndroid Build Coastguard Worker 	if (!conf || !conf->path)
62*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "path is empty");
63*49cdfc7eSAndroid Build Coastguard Worker 
64*49cdfc7eSAndroid Build Coastguard Worker 	if (access(conf->path, F_OK) != 0) {
65*49cdfc7eSAndroid Build Coastguard Worker 		if (conf->flags & TST_SR_SKIP_MISSING) {
66*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO | TERRNO, "Path not found: %s",
67*49cdfc7eSAndroid Build Coastguard Worker 				conf->path);
68*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
69*49cdfc7eSAndroid Build Coastguard Worker 		}
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker 		ttype = (conf->flags & TST_SR_TBROK_MISSING) ? TBROK : TCONF;
72*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(ttype | TERRNO, "Path not found: %s", conf->path);
73*49cdfc7eSAndroid Build Coastguard Worker 	}
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker 	if (access(conf->path, W_OK) != 0) {
76*49cdfc7eSAndroid Build Coastguard Worker 		if (conf->flags & TST_SR_SKIP_RO) {
77*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO | TERRNO, "Path is not writable: %s",
78*49cdfc7eSAndroid Build Coastguard Worker 				conf->path);
79*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
80*49cdfc7eSAndroid Build Coastguard Worker 		}
81*49cdfc7eSAndroid Build Coastguard Worker 
82*49cdfc7eSAndroid Build Coastguard Worker 		ttype = (conf->flags & TST_SR_TBROK_RO) ? TBROK : TCONF;
83*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(ttype | TERRNO, "Path is not writable: %s", conf->path);
84*49cdfc7eSAndroid Build Coastguard Worker 	}
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	fp = fopen(conf->path, "r");
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker 	if (fp == NULL) {
89*49cdfc7eSAndroid Build Coastguard Worker 		print_error(__LINE__, conf->flags & TST_SR_IGNORE_ERR,
90*49cdfc7eSAndroid Build Coastguard Worker 			"Failed to open '%s' for reading", conf->path);
91*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
92*49cdfc7eSAndroid Build Coastguard Worker 	}
93*49cdfc7eSAndroid Build Coastguard Worker 
94*49cdfc7eSAndroid Build Coastguard Worker 	ret = fgets(line, sizeof(line), fp);
95*49cdfc7eSAndroid Build Coastguard Worker 	fclose(fp);
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker 	if (ret == NULL) {
98*49cdfc7eSAndroid Build Coastguard Worker 		if (conf->flags & TST_SR_IGNORE_ERR)
99*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
100*49cdfc7eSAndroid Build Coastguard Worker 
101*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "Failed to read anything from '%s'",
102*49cdfc7eSAndroid Build Coastguard Worker 			conf->path);
103*49cdfc7eSAndroid Build Coastguard Worker 	}
104*49cdfc7eSAndroid Build Coastguard Worker 
105*49cdfc7eSAndroid Build Coastguard Worker 	tst_sys_conf_save_str(conf->path, line);
106*49cdfc7eSAndroid Build Coastguard Worker 
107*49cdfc7eSAndroid Build Coastguard Worker 	if (!conf->val)
108*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
109*49cdfc7eSAndroid Build Coastguard Worker 
110*49cdfc7eSAndroid Build Coastguard Worker 	fp = fopen(conf->path, "w");
111*49cdfc7eSAndroid Build Coastguard Worker 
112*49cdfc7eSAndroid Build Coastguard Worker 	if (fp == NULL) {
113*49cdfc7eSAndroid Build Coastguard Worker 		print_error(__LINE__, conf->flags & TST_SR_IGNORE_ERR,
114*49cdfc7eSAndroid Build Coastguard Worker 			"Failed to open '%s' for writing", conf->path);
115*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
116*49cdfc7eSAndroid Build Coastguard Worker 	}
117*49cdfc7eSAndroid Build Coastguard Worker 
118*49cdfc7eSAndroid Build Coastguard Worker 	iret = fputs(conf->val, fp);
119*49cdfc7eSAndroid Build Coastguard Worker 
120*49cdfc7eSAndroid Build Coastguard Worker 	if (iret < 0) {
121*49cdfc7eSAndroid Build Coastguard Worker 		print_error(__LINE__, conf->flags & TST_SR_IGNORE_ERR,
122*49cdfc7eSAndroid Build Coastguard Worker 			"Failed to write into '%s'", conf->path);
123*49cdfc7eSAndroid Build Coastguard Worker 	}
124*49cdfc7eSAndroid Build Coastguard Worker 
125*49cdfc7eSAndroid Build Coastguard Worker 	iret = fclose(fp);
126*49cdfc7eSAndroid Build Coastguard Worker 
127*49cdfc7eSAndroid Build Coastguard Worker 	if (iret < 0) {
128*49cdfc7eSAndroid Build Coastguard Worker 		print_error(__LINE__, conf->flags & TST_SR_IGNORE_ERR,
129*49cdfc7eSAndroid Build Coastguard Worker 			"Failed to close '%s'", conf->path);
130*49cdfc7eSAndroid Build Coastguard Worker 	}
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
133*49cdfc7eSAndroid Build Coastguard Worker }
134*49cdfc7eSAndroid Build Coastguard Worker 
tst_sys_conf_restore(int verbose)135*49cdfc7eSAndroid Build Coastguard Worker void tst_sys_conf_restore(int verbose)
136*49cdfc7eSAndroid Build Coastguard Worker {
137*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_sys_conf *i;
138*49cdfc7eSAndroid Build Coastguard Worker 
139*49cdfc7eSAndroid Build Coastguard Worker 	for (i = save_restore_data; i; i = i->next) {
140*49cdfc7eSAndroid Build Coastguard Worker 		if (verbose) {
141*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, "Restoring conf.: %s -> %s\n",
142*49cdfc7eSAndroid Build Coastguard Worker 				i->path, i->value);
143*49cdfc7eSAndroid Build Coastguard Worker 		}
144*49cdfc7eSAndroid Build Coastguard Worker 		FILE_PRINTF(i->path, "%s", i->value);
145*49cdfc7eSAndroid Build Coastguard Worker 	}
146*49cdfc7eSAndroid Build Coastguard Worker }
147*49cdfc7eSAndroid Build Coastguard Worker 
148