mausezahn: use getopt_long instead of getopt
[netsniff-ng.git] / proc.c
bloba0e649917477404d85d22d5657d3a162701170c9
1 #ifndef _GNU_SOURCE
2 # define _GNU_SOURCE
3 #endif
4 #include <sched.h>
5 #include <sys/wait.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <sys/resource.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <dirent.h>
14 #include "proc.h"
15 #include "die.h"
17 void cpu_affinity(int cpu)
19 int ret;
20 cpu_set_t cpu_bitmask;
22 CPU_ZERO(&cpu_bitmask);
23 CPU_SET(cpu, &cpu_bitmask);
25 ret = sched_setaffinity(getpid(), sizeof(cpu_bitmask),
26 &cpu_bitmask);
27 if (ret)
28 panic("Can't set this cpu affinity!\n");
31 int set_proc_prio(int priority)
33 int ret = setpriority(PRIO_PROCESS, getpid(), priority);
34 if (ret)
35 panic("Can't set nice val to %i!\n", priority);
37 return 0;
40 int set_sched_status(int policy, int priority)
42 int ret, min_prio, max_prio;
43 struct sched_param sp;
45 max_prio = sched_get_priority_max(policy);
46 min_prio = sched_get_priority_min(policy);
48 if (max_prio == -1 || min_prio == -1)
49 printf("Cannot determine scheduler prio limits!\n");
50 else if (priority < min_prio)
51 priority = min_prio;
52 else if (priority > max_prio)
53 priority = max_prio;
55 memset(&sp, 0, sizeof(sp));
56 sp.sched_priority = priority;
58 ret = sched_setscheduler(getpid(), policy, &sp);
59 if (ret) {
60 printf("Cannot set scheduler policy!\n");
61 return -EINVAL;
64 ret = sched_setparam(getpid(), &sp);
65 if (ret) {
66 printf("Cannot set scheduler prio!\n");
67 return -EINVAL;
70 return 0;
73 ssize_t proc_get_cmdline(unsigned int pid, char *cmdline, size_t len)
75 ssize_t ret;
76 char path[1024];
78 snprintf(path, sizeof(path), "/proc/%u/exe", pid);
79 ret = readlink(path, cmdline, len - 1);
80 if (ret < 0)
81 cmdline[0] = '\0';
82 else
83 cmdline[ret] = '\0';
85 return ret;
88 static int match_pid_by_inode(pid_t pid, ino_t ino)
90 struct dirent *ent;
91 char path[1024];
92 DIR *dir;
94 if (snprintf(path, sizeof(path), "/proc/%u/fd", pid) == -1)
95 panic("giant process name! %u\n", pid);
97 dir = opendir(path);
98 if (!dir)
99 return -1;
101 while ((ent = readdir(dir))) {
102 struct stat statbuf;
104 if (snprintf(path, sizeof(path), "/proc/%u/fd/%s",
105 pid, ent->d_name) < 0)
106 continue;
108 if (stat(path, &statbuf) < 0)
109 continue;
111 if (S_ISSOCK(statbuf.st_mode) && ino == statbuf.st_ino) {
112 closedir(dir);
113 return 0;
117 closedir(dir);
118 return -1;
121 int proc_find_by_inode(ino_t ino, char *cmdline, size_t len, pid_t *pid)
123 struct dirent *ent;
124 DIR *dir;
126 if (ino <= 0) {
127 cmdline[0] = '\0';
128 return 0;
131 dir = opendir("/proc");
132 if (!dir)
133 panic("Cannot open /proc: %s\n", strerror(errno));
135 while ((ent = readdir(dir))) {
136 int ret;
137 char *end;
138 const char *name = ent->d_name;
139 pid_t cur_pid = strtoul(name, &end, 10);
141 /* not a PID */
142 if (cur_pid == 0 && end == name)
143 continue;
145 ret = match_pid_by_inode(cur_pid, ino);
146 if (!ret) {
147 ret = proc_get_cmdline(cur_pid, cmdline, len);
148 if (ret < 0)
149 panic("Failed to get process cmdline: %s\n", strerror(errno));
151 closedir(dir);
152 *pid = cur_pid;
153 return ret;
157 closedir(dir);
158 return -1;
161 int proc_exec(const char *proc, char *const argv[])
163 int status;
164 pid_t pid;
166 pid = fork();
167 if (pid < 0) {
168 perror("fork");
169 return -1;
170 } else if (pid == 0) {
171 if (execvp(proc, argv) < 0)
172 fprintf(stderr, "Failed to exec: %s\n", proc);
173 _exit(1);
176 if (waitpid(pid, &status, 0) < 0) {
177 perror("waitpid");
178 return -2;
181 if (!WIFEXITED(status))
182 return -WEXITSTATUS(status);
184 return 0;
187 bool proc_exists(pid_t pid)
189 struct stat statbuf;
190 char path[1024];
192 if (snprintf(path, sizeof(path), "/proc/%u", pid) < 0)
193 return false;
195 return stat(path, &statbuf) == 0;