2016-05-23 79 views
0

因此,我必须打印某个PID的所有文件描述符的名称。我知道如何通过终端导航到proc/[pid]/fd来访问它,但我得到的只是有颜色的数字。我可以通过写ls -l得到他们的名字。在Linux上从C中打印PID文件描述符


我的问题是我怎么能打印C.这些名字我使用stat试过,但我无法得到它的工作,然后我用g_dir_open。它没有工作,因为我不能正确包括glib.h"galloca.h not found in glib.h")。

非常感谢你提前, 哦,请记住,我是一个完整的傻瓜,当涉及到Linux。

+3

*我是一个完全傻瓜,当谈到linux。*那么也许你的一点研究和努力会有很长的路要走。向我们展示您尝试过的[MCVE]。 – t0mm13b

+0

'然后我用g_dir_open':很好的向我们展示了这个代码.. :-) – sjsam

回答

2

通过使用readdirreadlink的组合,您可以获得所有描述符的绝对路径。在这个示例中,我使用了一个任意pid,您可以将其设置为一个命令行参数,或者您正在调用该函数。

#include <stdio.h> 
#include <fcntl.h> 
#include <limits.h> 
#include <string.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <unistd.h> 


int main(int argc, char *argv[]) 
{ 
    char *path = "/proc/3525/fd"; 
    DIR *fd_dir = opendir(path); 

    if (!fd_dir) { 
     perror("opendir"); 
     return 0; 
    } 

    struct dirent *cdir; 
    size_t fd_path_len = strlen(path) + 10; 
    char *fd_path = malloc(sizeof(char) * fd_path_len); 
    char *buf = malloc(sizeof(char) * PATH_MAX + 1); 

    while ((cdir = readdir(fd_dir))) { 
     if (strcmp(cdir->d_name, ".") == 0 || 
      strcmp(cdir->d_name, "..") == 0) 
      continue; 
     snprintf(fd_path, fd_path_len - 1, "%s/%s", path, cdir->d_name); 
     printf("Checking: %s\n", fd_path); 
     ssize_t link_size = readlink(fd_path, buf, PATH_MAX); 
     if (link_size < 0) 
      perror("readlink"); 
     else { 
      buf[link_size] = '\0'; 
      printf("%s\n", buf); 
     } 
     memset(fd_path, '0', fd_path_len); 
    } 

    closedir(fd_dir); 
    free(fd_path); 
    free(buf); 

    return 0; 
} 
+0

你可能想要跳过while循环中的'.'和'..'目录项,否则它们'从失败的调用到'readlink()'会产生'EINVAL'错误。 –

+0

@AndrewHenle你是对的,值得一提的是考虑到这个例子。我在'strchr'中编辑了''。'' – tijko

+2

请注意,['readlink()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html)不会null - 终止它的结果字符串,但它会告诉你读了多少个字符。 (是的,这是一个奇怪的设计!)所以,你需要捕获长度并使用它来设置空字节(通常是最好的选择),或者用printf(“%。* s \ n”, (int)numbytes,buf);',假设你在'numbytes'中捕获了长度。 –