C语言 给定一个子PID,如何得到父PID

doinxwow  于 2023-05-28  发布在  其他
关注(0)|答案(4)|浏览(215)

我正在做一个项目,我有一些PID,我必须找出其中哪些是僵尸进程,然后杀死他们的父进程,以杀死最初的僵尸进程。我不确定是否有任何方法可以找出给定PID的PPID是什么。任何帮助将不胜感激。

rsaldnfx

rsaldnfx1#

在ps命令的源代码中,有一个在proc/readproc.h中定义的名为get_proc_stats的函数,它(以及其他东西)返回给定pid的父pid。您需要安装libproc-dev才能获得此功能。然后,您可以执行以下操作:

#include <proc/readproc.h>
void printppid(pid_t pid) {
    proc_t process_info;
    get_proc_stats(pid, &process_info);
    printf("Parent of pid=%d is pid=%d\n", pid, process_info.ppid);
}

这是从here中提取的。我从来没有使用过这个,但根据作者,这可能是有帮助的。

g2ieeal7

g2ieeal72#

我已经包括了仅使用系统库的Linux和macOS/BSD版本。
一个纯C语言,只使用Linux的标准库:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXBUF      (BUFSIZ * 2)

int pgetppid(int pid) {
    int ppid;
    char buf[MAXBUF];
    char procname[32];  // Holds /proc/4294967296/status\0
    FILE *fp;

    snprintf(procname, sizeof(procname), "/proc/%u/status", pid);
    fp = fopen(procname, "r");
    if (fp != NULL) {
        size_t ret = fread(buf, sizeof(char), MAXBUF-1, fp);
        if (!ret) {
            return 0;
        } else {
            buf[ret++] = '\0';  // Terminate it.
        }
    }
    fclose(fp);
    char *ppid_loc = strstr(buf, "\nPPid:");
    if (ppid_loc) {
        ppid = sscanf(ppid_loc, "\nPPid:%d", &ppid);
        if (!ppid || ppid == EOF) {
            return 0;
        }
        return ppid;
    } else {
        return 0;
    }

}

int main () {
    int ppid, pid = 373;  // my current cron pid
    ppid = pgetppid(pid);
    printf("PPid = %d\n", ppid);
}

对于macOS和FreeBSD,请使用以下命令:

#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/param.h>
#include <sys/user.h>

int pgetppid(int pid) {

    struct kinfo_proc p;
    size_t len = sizeof(struct kinfo_proc);
    int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
    if (sysctl(mib, 4, &p, &len, NULL, 0) < 0)
        return 0;
    if (len == 0)
        return 0;
    int ret;
#if defined(__APPLE__)
        ret = p.kp_eproc.e_ppid; // macOS
    #elif defined(__FreeBSD__)
        ret = p.ki_ppid; // FreeBSD
    #else
        #error "Not supported, try adding an elif for this OS"
    #endif
    return ret;
}

int main () {
    int ppid, pid = 2420;  // my current cron pid
        ppid = pgetppid(pid);
    printf("PPid = %d\n", ppid);
}
egdjgwm8

egdjgwm83#

我在macOS上找到了一个替代解决方案,灵感来自another answer。您可以使用未文档化的“libproc”方法。
要在Swift中使用libproc,请在桥接头中添加以下行:

#import <libproc.h>

然后你可以使用以下示例代码获取ppid:

let pid = pid_t(12345)
var shortinfo = proc_bsdshortinfo()
let status = proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &shortinfo, Int32(MemoryLayout.size(ofValue: shortinfo)))
guard status > 0 else {
    let errno_stored = errno
    let errorDescription = String(cString:strerror(errno_stored)!)
    throw NSError(domain: "com.apple.libproc", code: Int(errno_stored), userInfo: [NSLocalizedDescriptionKey: errorDescription])
}
let ppid = pid_t(shortinfo.pbsi_ppid)
ryevplcw

ryevplcw4#

函数getppid()的作用是:

#include <unistd.h>

int main()
{
    pid_t ppid;

    ppid = getppid();

    return (0);
}

相关问题