-
Notifications
You must be signed in to change notification settings - Fork 0
/
readproc.c
151 lines (123 loc) · 2.87 KB
/
readproc.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "samlib.h"
#if defined(__linux__) || defined (__QNX__)
#include <dirent.h>
static int readproc(pid_t pid, const char *file, char *buf, int len)
{
char fname[32];
int fd, n;
*buf = 0;
strfmt(fname, sizeof(fname), "/proc/%u/%s", pid, file);
fd = open(fname, O_RDONLY);
if (fd < 0)
return -1;
n = read(fd, buf, len - 1);
close(fd);
/* Zero length is not an error. Some files, like a kernel thread
* cmdline, are zero length.
*/
if (n < 0)
return -1;
buf[n] = 0;
return n;
}
/* Note: /proc/pid/cmdline is limited to 4k */
int readproccmdline(pid_t pid, char *buf, int len)
{
int i, n = readproc(pid, "cmdline", buf, len);
if (n > 0)
for (i = 0; i < n - 1; ++i)
if (buf[i] == 0)
buf[i] = ' ';
return n;
}
int readproccmd(pid_t pid, char *buf, int len)
{
int n = readproc(pid, "cmdline", buf, len);
if (n > 0)
n = strlen(buf);
return n;
}
int readprocstat(pid_t pid, struct procstat_min *stat)
{
#ifdef __QNX__
errno = ENOSYS;
return -1;
#else
char buf[128];
int n = readproc(pid, "stat", buf, sizeof(buf));
if (n <= 0)
return n;
if (sscanf(buf, "%d (%[^)]) %c %d %d %d %*d %*d %*u "
"%*u %*u %*u %*u %*u %*u %*u "
"%*u %*u %*u %*u %*u %llu",
&stat->pid, stat->comm, &stat->state,
&stat->ppid, &stat->pgrp, &stat->session,
&stat->starttime) != 7)
return 1; /* can't happen */
return 0;
#endif
}
pid_t _findpid(const char *cmd, pid_t start_pid, char *buf, int len)
{
pid_t pid;
char *e;
struct dirent *ent;
DIR *dir = opendir("/proc");
if (!dir)
return 0;
while ((ent = readdir(dir))) {
pid = strtol(ent->d_name, &e, 10);
if (*e || pid <= start_pid)
continue;
readproccmdline(pid, buf, len);
if (strstr(buf, cmd)) {
closedir(dir);
return pid;
}
}
closedir(dir);
return 0;
}
pid_t findpid(const char *cmd, pid_t start_pid)
{
char buf[4097];
return _findpid(cmd, start_pid, buf, sizeof(buf));
}
#elif defined(WIN32)
#include <psapi.h>
int readproccmd(pid_t pid, char *buf, int len)
{
HMODULE hMod;
DWORD cbNeeded;
int rc = -1;
HANDLE nProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid);
if (nProc)
if (EnumProcessModules(nProc, &hMod, sizeof(hMod), &cbNeeded))
rc = GetModuleBaseNameA(nProc, hMod, buf, len);
CloseHandle(nProc);
return rc;
}
pid_t _findpid(const char *cmd, pid_t start_pid, char *buf, int len)
{
DWORD procs[1024], cbNeeded, cProcesses;
unsigned int i;
if (!EnumProcesses(procs, sizeof(procs), &cbNeeded))
return 0;
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++)
if (procs[i] != 0 && procs[i] > start_pid)
if (readproccmd(procs[i], buf, len) > 0)
if (strstr(buf, cmd))
return procs[i];
return 0;
}
pid_t findpid(const char *cmd, pid_t start_pid)
{
char buf[MAX_PATH];
return _findpid(cmd, start_pid, buf, sizeof(buf));
}
#endif