linux exec函數執行之前設置當前進程所有描述符FD_CLOEXEC

1、查看進程打開的描述符

ll /proc/$PID/fd

在這裏插入圖片描述

2、C語言獲取當前進程打開的fd並設置FD_CLOEXEC

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include<stdint.h>


/* 將當前進程打開的所有描述符標誌設置爲CLOEXEC */
static void SetFDFlagToCLOEXEC(char* fd_path)
{
    if(!fd_path)
        return;
    //fcntl(fd,F_SETFD,FD_CLOEXEC); /* 設置exec時關閉 */
    
    DIR *dir;
    struct dirent *ptr;
    if ((dir = opendir(fd_path)) == NULL)
    {
        perror("Open dir error...");
        cout << " opendir error " << strerror(errno);
        return;
    }

    int fd = 0;
    while ((ptr = readdir(dir)) != NULL)
    {
        if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)
            continue;
        
        fd = atoi(ptr->d_name);
        //if(fd == 0 || fd == 1 || fd == 2)
        //{
        //    continue;
        //}
        
        if(ptr->d_type == 8)    ///file
        {
            cout << " FD is " << ptr->d_name;
            fcntl(fd, F_SETFD, FD_CLOEXEC);
        }
        else if(ptr->d_type == 10)    ///link file
        {
            LOG_DEBUG << " FD is " << ptr->d_name;
            int ret = 0;
            //int ret = fcntl(fd, F_GETFD, 0);
            //cout << " ret&FD_CLOEXEC " << (ret&FD_CLOEXEC);
            
            fcntl(fd, F_SETFD, FD_CLOEXEC);
            ret = fcntl(fd, F_GETFD, 0);
            if(ret&FD_CLOEXEC)
            {
                cout << "exec運行 時該描述符關閉";
            }
        }
        else if(ptr->d_type == 4)    ///dir
        {
           
        }
    }
    
    closedir(dir);
    
}

int main()
{
	pid_t pid = getpid();
    char fd_path[64];
    memset(fd_path, 0, 64);
    snprintf(fd_path, 64, "/proc/%d/fd", pid);
    
    if (access(fd_path, 0) == -1)
    {
       /* 文件夾不存在 */
    }
    else
    {
        SetFDFlagToCLOEXEC(fd_path);
    }
    
    execv("demo", NULL);
}

3、參考

《1》、linux 根據進程號查看進程打開的所有文件描述符

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章