使用popen函数和ps命令读取进程表

     #include <stdio.h>      /* FILE, sprintf, fgets, puts */
     #include <stdlib.h>     /* atoi, exit, EXIT_SUCCESS */
     #include <string.h>     /* strtok, strcmp */
     #include <sys/types.h>  /* pid_t */
     #include <sys/wait.h>   /* WIFEXITED, WEXITSTATUS */
    
     char *procname(pid_t pid)
     {
        static char line[133], command[80], *linep, *token, *cmd;
        FILE *fp;
        int status;
    
        if (0 == pid) return (char *)0;
    
        sprintf(command, "ps -p %d 2>/dev/null", pid);
        fp = popen(command, "r");
        if ((FILE *)0 == fp) return (char *)0;
    
        /* 读取标题行 */
        if ((char *)0 == fgets(line, sizeof line, fp))
        {
           pclose(fp);
           return (char *)0;
        }
    
        /* 从标题栏分析出命令名所在列。
         * (BSD风格的系统将指示命令的"COMMAND"字符串放在第5列,SysV好象将
         * 指示命令的“CMD”或“COMMAND”字符串放在第4列)
         */
        for (linep = line; ; linep = (char *)0)
        {
           if ((char *)0 == (token = strtok(linep, " \t\n")))
           {
              pclose(fp);
              return (char *)0;
           }
           if (0 == strcmp("COMMAND", token) || 0 == strcmp("CMD", token))
           { /*  我们找到COMMAND所在列 */
              cmd = token;
              break;
           }
        }
    
        /* 读取 ps(1) 输出行 */
        if ((char *)0 == fgets(line, sizeof line, fp))
        {
           pclose(fp);
           return (char *)0;
        }
    
        /* 抓COMMAND标题下面的词 ... */
        if ((char *)0 == (token = strtok(cmd, " \t\n")))
        {
           pclose(fp);
           return (char *)0;
        }
    
        status = pclose(fp);
        if (!WIFEXITED(status) || 0 != WEXITSTATUS(status))
          return (char *)0;
    
        return token;
     }
    
     int main(int argc, char *argv[])
     {
        puts(procname(atoi(argv[1])));
        exit(EXIT_SUCCESS);
     }