2012-06-27 2 views
6

가능한 중복 : 여기 기능이
Getting Filename from file descriptor in C
Obtain filename from file pointer in CFILE 포인터가 주어지면 파일 이름을 어떻게 찾을 수 있습니까?

:

handle_file(FILE *file) 
{ 
    if(condition) 
    { 
     print filename and other msg; 
    } 
} 

여기서 우리가 알고있는 유일한 방법은 파일에 대한 포인터입니다; 포인터에 따라 파일 이름을 가져올 수 있습니까?

+1

나는 이것이 가능하지 않다고 생각합니다. 파일 이름을 별도로 추적해야합니다. –

+0

불가능합니다. 어쨌든 [이 체크] (http://stackoverflow.com/questions/9937645/obtain-filename-from-file-pointer-in-c) – tuxuday

+0

어떤 운영 체제? – hmjd

답변

15

파일 설명자를 얻기 위해 this answer을 확인하고 파일 설명 자로 파일 이름을 가져 오려면 this answer을 확인하십시오. Linux에서 정상이어야합니다 (다른 운영 체제에 대해서는 확실하지 않음).

여기 (Cygwin에서/Win7에에서 테스트) 빠른 작업 예제 :

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

int main() 
{ 
    int MAXSIZE = 0xFFF; 
    char proclnk[0xFFF]; 
    char filename[0xFFF]; 
    FILE *fp; 
    int fno; 
    ssize_t r; 

    // test.txt created earlier 
    fp = fopen("test.txt", "r"); 
    if (fp != NULL) 
    { 
     fno = fileno(fp); 
     sprintf(proclnk, "/proc/self/fd/%d", fno); 
     r = readlink(proclnk, filename, MAXSIZE); 
     if (r < 0) 
     { 
      printf("failed to readlink\n"); 
      exit(1); 
     } 
     filename[r] = '\0'; 
     printf("fp -> fno -> filename: %p -> %d -> %s\n", 
       fp, fno, filename); 
    } 
    return 0; 
} 

출력 : 루트하고 lsof 명령 만약 내가 검색으로

fp -> fno -> filename: 0x80010294 -> 3 -> /tmp/test.txt 
+1

+1 : 도움이되는 발견. 가독성을 높이기 위해 답을 약간 형식을 지정했습니다. –

+0

나는 파일 이름 뒤에/proc/self/fd/xxx를 출력한다는 것을 제외하고는 아주 잘 작동 해 보았습니다. – nzomkxia

+0

이 댓글은 어떨까요 : "/ proc/self/fd/NNN에서'readlink'를 사용할 수 있습니다. 여기서 NNN은 파일 설명자입니까?readlink를 사용해 보셨습니까? – bcelary

0

, 시스템에 존재한다 fileno(fp)을 사용하여 시작 파일 설명자 (lsof -d descriptor)를 가져올 수 있습니다. 너도해볼 수있어.

-2

나는 가능하다고 생각합니다.
fileno(fp)을 사용하여 설명자를 가져옵니다.
그런 다음 fstat() 기능을 사용할 수 있습니다.

The fstat() function shall obtain information about an open file asso‐ 
     ciated with the file descriptor fildes, and shall write it to the area 
     pointed to by buf. 
다음

int fstat(int fildes, struct stat *buf);

, 당신은 당신의 *buf에 파일 정보]를 많이 얻을 수 있습니다.

+2

fstat에 의해 반환 된 구조는 파일 이름을 포함하지 않습니다. http://linux.die.net/man/2/fstat를 참조하십시오. – bcelary

-1

그렇지 않으면 폴더의 모든 디렉토리와 파일을 분석하려면 opendir과 struct dirent를 사용할 수 있습니다. 이것은 파일 포인터를 사용하지 않지만 코드가 작동하는 방식에 따라 유용 할 수 있습니다.

DIR *BaseDIR; 
struct dirent *curentDir; 
BaseDIR = opendir("path/to/the/directory"); 
while((curentDir = readdir(BaseDIR)) != NULL){ 
     printf("directory or file name : %s\n",curentDir->d_name); 
} 
closedir(BaseDIR); 
2

이것은 2 단계로 수행 할 수 있습니다. 먼저 파일 디스크립터를 얻어야한다. 그런 다음 파일 이름을 복구해야한다. 다음은 예제이지만 심각한 버퍼 오버 플로우 취약점이 있습니다!

#include <stdio.h> 
#include <unistd.h> 

char * recover_filename(FILE * f) { 
    int fd; 
    char fd_path[255]; 
    char * filename = malloc(255); 
    ssize_t n; 

    fd = fileno(f); 
    sprintf(fd_path, "/proc/self/fd/%d", fd); 
    n = readlink(fd_path, filename, 255); 
    if (n < 0) 
     return NULL; 
    filename[n] = '\0'; 
    return filename; 
} 
+0

OpenBSD는 어떻습니까? – user2284570