2016-05-23 123 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'中捕獲了長度。 –