以下代码循环遍历curr_task
的祖先,一直到swapper
进程(即任何Linux进程的“最遥远的”祖先),它停止,因为{{1} }。
swapper == swapper->parent
问题是我还想获得while (curr_task != curr_task->parent)
...get curr_task info
curr_task = curr_task->parent
进程的信息。有几种明显的方法可以做到这一点(例如,在while循环之后的swapper
语句,或者在获得goto
信息的循环之后的单个if
语句。但是,这些显而易见的解决方案似乎相当不优雅,因此我正在寻找一种更简洁的解决方案,它不涉及备受much swapper
或复制/粘贴代码。
答案 0 :(得分:2)
使用某些功能执行以下操作。
walk_tasks_backwards_from(current);
功能跟随......
static void walk_tasks_backwards_from(struct task_struct *pos);
static void process_tasks(struct task_struct *parent, struct task_struct *child);
static void process_tasks(struct task_struct *parent, struct task_struct *child) {
pr_alert("parent process: %s, PID: %d\n", parent->comm, parent->pid);
pr_alert("child process: %s, PID: %d\n", child->comm , child->pid);
}
static void walk_tasks_backwards_from(struct task_struct *pos) {
struct task_struct *parent; ;
do {
parent = pos->parent;
process_tasks(parent, pos);
pos = parent;
} while(parent->pid != 0);
}
您可以使用当前或任何想要走的任务来调用该函数,即
walk_tasks_backwards_from(current);
这会在我的机器上产生以下输出,我有一个玩具内核模块,我可以使用cat /dev/toy
[161769.300609] parent process: bash, PID: 918
[161769.301299] child process: cat, PID: 2803
[161769.301973] parent process: login, PID: 626
[161769.302632] child process: bash, PID: 918
[161769.303216] parent process: systemd, PID: 1
[161769.303797] child process: login, PID: 626
[161769.304355] parent process: swapper/0, PID: 0
[161769.304978] child process: systemd, PID: 1
或者您可以使用以下任何一种......
使用do {} while
task = current;// Get current process
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
do {
task = task->parent;
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
} while (task->pid != 0);
//task here has pid == 0;
或使用while循环。
task = current;// Get current process
while (task->pid != 0) {
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
task = task->parent;
}
//task here has pid == 0;
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
循环所有
struct task_struct task;
for_each_process(task) {
printk(KERN_INFO "process: %s, PID: %d", task->comm, task->pid);
}
答案 1 :(得分:2)
这是一种方法:使用另一个变量。
struct task_struct *t, *prev;
t = current;
do {
// do something with t
prev = t;
t = t->parent;
} while (prev->pid != 0);
或者将其移入函数:
int move_up(struct task **tp) {
int was_swapper = ((*tp)->pid == 0);
*tp = (*tp)->parent;
return was_swapper;
}
// ...
struct task_struct *t = current;
do {
// do something with t
} while (move_up(&t));
答案 2 :(得分:0)
实际上,我们需要RCU锁来保护我们免于崩溃:
public Object alienProxy() {
try {
System.setProperty("https.proxyUser", user);
System.setProperty("https.proxyPassword", pass);
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", port);
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
System.setProperty("jdk.http.auth.proxying.disabledSchemes", "");
URL server = new URL(myURL);
HttpURLConnection connection = (HttpURLConnection) server.openConnection();
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
});
try {
connection.connect();
} catch (Exception e) {
e.printStackTrace();
System.clearProperty("https.proxyUser");
System.clearProperty("https.proxyPassword");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
return "Invalid prxy";
}
connection.disconnect();
System.clearProperty("https.proxyUser");
System.clearProperty("https.proxyPassword");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
return service1();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}`