xref: /aosp_15_r20/external/ltp/lib/tst_process_state.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) 2012-2014 Cyril Hrubis [email protected]
4*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2021 Xie Ziyao <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker  */
6*49cdfc7eSAndroid Build Coastguard Worker 
7*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
8*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
9*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
10*49cdfc7eSAndroid Build Coastguard Worker 
11*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
12*49cdfc7eSAndroid Build Coastguard Worker #include "tst_process_state.h"
13*49cdfc7eSAndroid Build Coastguard Worker 
tst_process_state_wait(const char * file,const int lineno,void (* cleanup_fn)(void),pid_t pid,const char state,unsigned int msec_timeout)14*49cdfc7eSAndroid Build Coastguard Worker int tst_process_state_wait(const char *file, const int lineno,
15*49cdfc7eSAndroid Build Coastguard Worker 			   void (*cleanup_fn)(void), pid_t pid,
16*49cdfc7eSAndroid Build Coastguard Worker 			   const char state, unsigned int msec_timeout)
17*49cdfc7eSAndroid Build Coastguard Worker {
18*49cdfc7eSAndroid Build Coastguard Worker 	char proc_path[128], cur_state;
19*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int msecs = 0;
20*49cdfc7eSAndroid Build Coastguard Worker 
21*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(proc_path, sizeof(proc_path), "/proc/%i/stat", pid);
22*49cdfc7eSAndroid Build Coastguard Worker 
23*49cdfc7eSAndroid Build Coastguard Worker 	for (;;) {
24*49cdfc7eSAndroid Build Coastguard Worker 		safe_file_scanf(file, lineno, cleanup_fn, proc_path,
25*49cdfc7eSAndroid Build Coastguard Worker 				"%*[^)]%*c %c", &cur_state);
26*49cdfc7eSAndroid Build Coastguard Worker 
27*49cdfc7eSAndroid Build Coastguard Worker 		if (state == cur_state)
28*49cdfc7eSAndroid Build Coastguard Worker 			break;
29*49cdfc7eSAndroid Build Coastguard Worker 
30*49cdfc7eSAndroid Build Coastguard Worker 		usleep(1000);
31*49cdfc7eSAndroid Build Coastguard Worker 		msecs += 1;
32*49cdfc7eSAndroid Build Coastguard Worker 
33*49cdfc7eSAndroid Build Coastguard Worker 		if (msec_timeout && msecs >= msec_timeout) {
34*49cdfc7eSAndroid Build Coastguard Worker 			errno = ETIMEDOUT;
35*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
36*49cdfc7eSAndroid Build Coastguard Worker 		}
37*49cdfc7eSAndroid Build Coastguard Worker 	}
38*49cdfc7eSAndroid Build Coastguard Worker 
39*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
40*49cdfc7eSAndroid Build Coastguard Worker }
41*49cdfc7eSAndroid Build Coastguard Worker 
tst_process_state_wait2(pid_t pid,const char state)42*49cdfc7eSAndroid Build Coastguard Worker int tst_process_state_wait2(pid_t pid, const char state)
43*49cdfc7eSAndroid Build Coastguard Worker {
44*49cdfc7eSAndroid Build Coastguard Worker 	char proc_path[128], cur_state;
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(proc_path, sizeof(proc_path), "/proc/%i/stat", pid);
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker 	for (;;) {
49*49cdfc7eSAndroid Build Coastguard Worker 		FILE *f = fopen(proc_path, "r");
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker 		if (!f) {
52*49cdfc7eSAndroid Build Coastguard Worker 			fprintf(stderr, "Failed to open '%s': %s\n",
53*49cdfc7eSAndroid Build Coastguard Worker 				proc_path, strerror(errno));
54*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
55*49cdfc7eSAndroid Build Coastguard Worker 		}
56*49cdfc7eSAndroid Build Coastguard Worker 
57*49cdfc7eSAndroid Build Coastguard Worker 		if (fscanf(f, "%*[^)]%*c %c", &cur_state) != 1) {
58*49cdfc7eSAndroid Build Coastguard Worker 			fclose(f);
59*49cdfc7eSAndroid Build Coastguard Worker 			fprintf(stderr, "Failed to read '%s': %s\n",
60*49cdfc7eSAndroid Build Coastguard Worker 				proc_path, strerror(errno));
61*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
62*49cdfc7eSAndroid Build Coastguard Worker 		}
63*49cdfc7eSAndroid Build Coastguard Worker 		fclose(f);
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker 		if (state == cur_state)
66*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker 		usleep(10000);
69*49cdfc7eSAndroid Build Coastguard Worker 	}
70*49cdfc7eSAndroid Build Coastguard Worker }
71*49cdfc7eSAndroid Build Coastguard Worker 
tst_process_exit_wait(pid_t pid,unsigned int msec_timeout)72*49cdfc7eSAndroid Build Coastguard Worker int tst_process_exit_wait(pid_t pid, unsigned int msec_timeout)
73*49cdfc7eSAndroid Build Coastguard Worker {
74*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int msecs = 0;
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker 	for (;;) {
77*49cdfc7eSAndroid Build Coastguard Worker 		if (kill(pid, 0) && errno == ESRCH)
78*49cdfc7eSAndroid Build Coastguard Worker 			break;
79*49cdfc7eSAndroid Build Coastguard Worker 
80*49cdfc7eSAndroid Build Coastguard Worker 		usleep(1000);
81*49cdfc7eSAndroid Build Coastguard Worker 		msecs += 1;
82*49cdfc7eSAndroid Build Coastguard Worker 
83*49cdfc7eSAndroid Build Coastguard Worker 		if (msec_timeout && msecs >= msec_timeout) {
84*49cdfc7eSAndroid Build Coastguard Worker 			errno = ETIMEDOUT;
85*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
86*49cdfc7eSAndroid Build Coastguard Worker 		}
87*49cdfc7eSAndroid Build Coastguard Worker 	}
88*49cdfc7eSAndroid Build Coastguard Worker 
89*49cdfc7eSAndroid Build Coastguard Worker 	return 1;
90*49cdfc7eSAndroid Build Coastguard Worker }
91