forked from scanmem/scanmem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.c
94 lines (79 loc) · 2.46 KB
/
common.c
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
/*
Common helper and utility functions
Copyright (C) 2018 Sebastian Parschauer <s.parschauer(a)gmx.de>
This file is part of libscanmem.
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include "common.h"
/* states returned by check_process() */
enum pstate {
PROC_RUNNING,
PROC_ERR, /* error during detection */
PROC_DEAD,
PROC_ZOMBIE
};
/*
* We check if a process is running in /proc directly.
* Also zombies are detected.
*
* Requirements: Linux kernel, mounted /proc
* Assumption: (pid > 0) --> Please check your PID before!
*/
static enum pstate check_process(pid_t pid)
{
FILE *fp = NULL;
char *line = NULL;
size_t alloc_len = 0;
char status = '\0';
char path_str[128] = "/proc/";
int pr_len, path_len = sizeof("/proc/") - 1;
/* append $pid/status and check if file exists */
pr_len = sprintf((path_str + path_len), "%d/status", pid);
if (pr_len <= 0)
goto err;
path_len += pr_len;
fp = fopen(path_str, "r");
if (!fp) {
if (errno != ENOENT)
goto err;
else
return PROC_DEAD;
}
/* read process status */
while (getline(&line, &alloc_len, fp) != -1) {
if (alloc_len <= sizeof("State:\t"))
continue;
if (strncmp(line, "State:\t", sizeof("State:\t") - 1) == 0) {
status = line[sizeof("State:\t") - 1];
break;
}
}
if (line)
free(line);
fclose(fp);
if (status < 'A' || status > 'Z')
goto err;
/* zombies are not running - parent doesn't wait */
if (status == 'Z' || status == 'X')
return PROC_ZOMBIE;
return PROC_RUNNING;
err:
return PROC_ERR;
}
bool sm_process_is_dead(pid_t pid)
{
return (check_process(pid) != PROC_RUNNING);
}