sourcecode

프로세스 리눅스(C 코드)에 대한 열린 파일 설명자 찾기?

copyscript 2023. 10. 16. 21:59
반응형

프로세스 리눅스(C 코드)에 대한 열린 파일 설명자 찾기?

리눅스에서 프로세스를 위해 열려있는 모든 fds를 찾고 싶었습니다.

glib 라이브러리 기능으로 할 수 있습니까?

여기 제가 예전에 사용했던 코드가 있습니다. /proc/self(thxDonal!)에 대해서는 몰랐지만, 어쨌든 이 방법이 더 일반적일 것입니다.맨 위에 모든 기능에 필요한 내용을 포함시켰습니다.

#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/resource.h>

#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif

/* implementation of Donal Fellows method */ 
int get_num_fds()
{
     int fd_count;
     char buf[64];
     struct dirent *dp;

     snprintf(buf, 64, "/proc/%i/fd/", getpid());

     fd_count = 0;
     DIR *dir = opendir(buf);
     while ((dp = readdir(dir)) != NULL) {
          fd_count++;
     }
     closedir(dir);
     return fd_count;
}

한 번 파일 핸들이 유출되는 매우 심각한 문제를 겪었는데, Tom H.가 제안한 해결책을 실제로 코딩한 것으로 드러났습니다.

/* check whether a file-descriptor is valid */
int pth_util_fd_valid(int fd)
{
     if (fd < 3 || fd >= FD_SETSIZE)
          return FALSE;
     if (fcntl(fd, F_GETFL) == -1 && errno == EBADF)
          return FALSE;
     return TRUE;
}

/* check first 1024 (usual size of FD_SESIZE) file handles */
int test_fds()
{
     int i;
     int fd_dup;
     char errst[64];
     for (i = 0; i < FD_SETSIZE; i++) {
          *errst = 0;
          fd_dup = dup(i);
          if (fd_dup == -1) {
                strcpy(errst, strerror(errno));
                // EBADF  oldfd isn’t an open file descriptor, or newfd is out of the allowed range for file descriptors.
                // EBUSY  (Linux only) This may be returned by dup2() during a race condition with open(2) and dup().
                // EINTR  The dup2() call was interrupted by a signal; see signal(7).
                // EMFILE The process already has the maximum number of file descriptors open and tried to open a new one.
          } else {
                close(fd_dup);
                strcpy(errst, "dup() ok");
          }
          printf("%4i: %5i %24s %s\n", i, fcntl(i, F_GETOWN), fd_info(i), errst);
     }
     return 0;
}

당신도 아마 이것들을 원할 겁니다. 위의 마지막 인쇄물을 만족시키기 위해서...

char *fcntl_flags(int flags)
{
    static char output[128];
    *output = 0;

    if (flags & O_RDONLY)
        strcat(output, "O_RDONLY ");
    if (flags & O_WRONLY)
        strcat(output, "O_WRONLY ");
    if (flags & O_RDWR)
        strcat(output, "O_RDWR ");
    if (flags & O_CREAT)
        strcat(output, "O_CREAT ");
    if (flags & O_EXCL)
        strcat(output, "O_EXCL ");
    if (flags & O_NOCTTY)
        strcat(output, "O_NOCTTY ");
    if (flags & O_TRUNC)
        strcat(output, "O_TRUNC ");
    if (flags & O_APPEND)
        strcat(output, "O_APPEND ");
    if (flags & O_NONBLOCK)
        strcat(output, "O_NONBLOCK ");
    if (flags & O_SYNC)
        strcat(output, "O_SYNC ");
    if (flags & O_ASYNC)
        strcat(output, "O_ASYNC ");

    return output;
}

char *fd_info(int fd)
{
    if (fd < 0 || fd >= FD_SETSIZE)
        return FALSE;
    // if (fcntl(fd, F_GETFL) == -1 && errno == EBADF)
    int rv = fcntl(fd, F_GETFL);
    return (rv == -1) ? strerror(errno) : fcntl_flags(rv);
}

FD_SETSIZE는 보통 1024이고 프로세스당 최대 파일 수는 보통 1024입니다.확인하려면 TomH에서 설명한 대로 이 기능에 대한 호출로 대체할 수 있습니다.

#include <sys/time.h>
#include <sys/resource.h>

rlim_t get_rlimit_files()
{
    struct rlimit rlim;
    getrlimit(RLIMIT_NOFILE, &rlim);
    return rlim.rlim_cur;
}   

이 모든 것을 하나의 파일로 통합하면(확인을 위해) 이와 유사한 출력을 생성하여 광고대로 작동하는지 확인할 수 있습니다.

0:     0                  O_RDWR  dup() ok
1:     0                O_WRONLY  dup() ok
2:     0                  O_RDWR  dup() ok
3:     0              O_NONBLOCK  dup() ok
4:     0     O_WRONLY O_NONBLOCK  dup() ok
5:    -1      Bad file descriptor Bad file descriptor
6:    -1      Bad file descriptor Bad file descriptor
7:    -1      Bad file descriptor Bad file descriptor
8:    -1      Bad file descriptor Bad file descriptor
9:    -1      Bad file descriptor Bad file descriptor

저는 여러분이 질문한 것에 대한 답을 얻기를 바라고, 궁금하실 경우를 대비하여 OP가 질문한 것에 대한 답을 찾기 위해 여기에 왔습니다. 그리고 그 답을 읽었을 때, 제가 이미 몇 년 전에 코드를 작성했다는 것을 기억하세요.즐거운 시간 되세요.

를에(하게)를수 /proc파일 시스템이 마운트되었습니다. 쉬운 방법이다 것이라는 합니다./proc/self/fd을 따서 (; 은 FD 의를 사용합니다.g_dir_open,g_dir_read_name그리고.g_dir_close물론 목록 작성을 위해서입니다.)

그렇지 않으면 정보를 얻는 것이 다소 어색합니다(예를 들어 유용한 POSIX API가 없습니다. 이 영역은 표준화되지 않은 영역입니다).

pid를 통해 프로세스를 식별할 수 있다면 간단히 수행할 수 있습니다.

ls -l /proc/<pid>/fd | wc - l

C에서는 모든 것을 파이프링하여 출력을 재사용하거나 위의 디렉토리에서 파일을 직접 셀 수 있습니다(: C를 사용하여 디렉토리의 파일 수를 계산하는 방법).

Boost::file system을 사용하는 Donal의 솔루션인 C++를 선택할 수 있는 경우도 있습니다.

#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <unistd.h>

namespace fs = boost::filesystem;

int main()
{
    std::string path = "/proc/" + std::to_string(::getpid()) + "/fd/";
    unsigned count = std::distance(fs::directory_iterator(path),
                                   fs::directory_iterator());
    std::cout << "Number of opened FDs: " << count << std::endl;
}

방식으로 할 수 한 모든 인() 입니다() ).getrlimit()읽다RLIMIT_NOFILE범위를 찾다) 같은 것을 부르다fcntl(fd, F_GETFD, 0)각각의 응답을 확인하고 EBADF 응답을 확인하여 열려 있지 않은 응답을 확인합니다.

셸에서 프로세스가 열려 있는 파일을 찾고 싶다면,lsof -p <pid>당신이 원하는 겁니다

fstat 명령어는 시스템의 모든 실행 프로세스와 열린 디스크립터를 나열합니다. 더 나아가 디스크립터가 어떤 종류의 디스크립터인지(파일, 소켓, 파이프 등)를 나열하며 디스크립터가 그 파일 시스템의 어떤 파일 시스템과 어떤 inode 번호에 무엇을 읽거나 쓰고 있는지 힌트를 주려고 합니다.

언급URL : https://stackoverflow.com/questions/6583158/finding-open-file-descriptors-for-a-process-linux-c-code

반응형