linux系统命令ps和top都是通过读取/proc/$PID 目录下的信息获取进程的相关信息, 它遍历/proc目录下的首字符为数字的目录,获取系统进程的信息。
我们经常会把pid写到/var/run/xxx.pid中,可能会有获取该进程相关信息的需要,可以通过读取/proc/$PID取得ps命令可获取的一切进程信息。
下面是通过PID获取进程cmdline的实现:
/*
* getcmdline.c
*
* Copyright (C) 2011 crazyleen <ruishenglin@126.com>
*
*/
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/*
* get cmdline from PID. Read progress info form /proc/$PID.
*/
static int read_to_buf(const char *filename, void *buf, int len)
{
int fd;
int ret;
if(buf == NULL || len < 0){
printf("%s: illegal para\n", __func__);
return -1;
}
memset(buf, 0, len);
fd = open(filename, O_RDONLY);
if(fd < 0){
perror("open:");
return -1;
}
ret = read(fd, buf, len);
close(fd);
return ret;
}
static char *get_cmdline_from_pid(int pid, char *buf, int len)
{
char filename[32];
char *name = NULL;
int n = 0;
if(pid < 1 || buf == NULL || len < 0){
printf("%s: illegal para\n", __func__);
return NULL;
}
snprintf(filename, 32, "/proc/%d/cmdline", pid);
n = read_to_buf(filename, buf, len);
if(n < 0)
return NULL;
if(buf[n-1]=='\n')
buf[--n] = 0;
name = buf;
while(n) {
if(((unsigned char)*name) < ' ')
*name = ' ';
name++;
n--;
}
*name = 0;
name = NULL;
if(buf[0])
return buf;
return NULL;
}
int main(int argc, char **argv)
{
char buf[1024];
printf("============\n");
printf("argv[0]: %s\n", argv[0]);
get_cmdline_from_pid(getppid(), buf, 1024);
printf("PPID [ %d ] cmdline: %s\n", getppid(), buf);
;
printf("PID [ %d ] cmdline: %s\n", getpid(), get_cmdline_from_pid(getpid(), buf, 1024));
printf("init [ 1 ] cmdline: %s\n", get_cmdline_from_pid(1, buf, 1024));
printf("============\n");
return 0;
}
输出结果:
$ gcc getcmdline.c && ./a.out -d 22
============
argv[0]: ./a.out
PPID [ 21751 ] cmdline: /bin/bash
PID [ 22515 ] cmdline: ./a.out -d 22
init [ 1 ] cmdline: /sbin/init
============