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