유닉스 / 리눅스 프로그래밍 환경 : 이해 dirfd 매개 변수

배경

유닉스 환경 프로그래밍, 시스템은 많이 제공하는 at등, 함수의 끝 openat, fstatat등, 이러한 기능은 일반적으로 기능이 다중 매개 변수 목록은int dirfd

예를 들면 :

int open(const char *pathname, int flags, mode_t mode);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

int mkfifo(const char *pathname, mode_t mode);
int mkfifoat(int dirfd, const char *pathname, mode_t mode);

...

의미

dirfd 파라미터를 의미한다 :
1)로 파라미터 절대 경로로 지정된 경우, FD는 함수 openat 무시된다 개방 기능에 해당
상대 경로 이름, FD 파라미터 지정 파일 시스템의 상대적인 경로명으로 지정된 2) 경로 파라미터 주소를 시작합니다. FD 인수가있는 디렉토리를 열어 상대 경로 이름을 얻는 것입니다. 이 시간에 따라서는 디렉토리 경로 기술자가 참조 dirfd를 기준으로합니다.
3) 경로 파라미터는 상대적 경로명을 지정 하고 FD 특별한 파라미터 값 AT_FDCWD이다. 동작의 기능과 유사한 기능 openat 오픈이 경우 현재 작업 디렉토리에서 취득 경로 이름.

실제로, dirfd파라미터는 위치 상대 경로 + 파일 기술자 (아닌 상대 경로 위치 +와 현재 작업 경로)로서의 기능을 실현한다. 우리는이 기능을 주셔서 감사합니다 아래 설명 된 문서를 참조 할 수 있습니다 :

경로 이름에 주어진 경로가 상대적인 경우 , (같은 상대 경로에 대한에서는 mkfifo ()에 의해 수행되는 것이 아니라 호출 프로세스의 현재 작업 디렉토리를 기준으로) 디렉토리에 상대적는 파일 기술자 dirfd에 의해 참조 해석 .
주어진 경로 이름이 상대적이라면,이 패스로 해석됩니다 디렉토리의 파일 기술자에 대한 상대 참조 dirfd (오히려 호출 프로세스의 현재 작업 디렉토리에 상대적보다).

용법

다음과 같이 각각 두 가지 방법으로 사용 :

다음과 같이 (1)는 첫 번째 파라미터의 값으로, 직접 오픈 디렉토리 연 코드는 openat :

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
 
void creat_at(char *dir_path, char *relative_path)
{
    int dir_fd;
    int fd;
    int flags;
    mode_t mode;
 
    dir_fd = open(dir_path, O_RDONLY);
    if (dir_fd < 0) 
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
 
    flags = O_CREAT | O_TRUNC | O_RDWR | O_DIRECTORY;
    mode = 0640;
    fd = openat(dir_fd, relative_path, flags, mode);
    if (fd < 0) 
    {
        perror("openat");
        exit(EXIT_FAILURE);
    }
 
    write(fd, "HELLO", 5);
 
    close(fd);
    close(dir_fd);
}
 
int main()
{
    creat_at("./open", "log.txt");
    return 0;
}

2, dirfd을 빌려됩니다 DIR*INT 설명을 입력 변환

#include <sys/types.h>
#include <dirent.h>

int dirfd(DIR *dirp);

다음과 같이 전체 코드는 다음과 같습니다

#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
 
int main()
{
    DIR *dir;
    int dirfd2;
    int fd;
    int n;
 
    dir = opendir("./open/chl");
    if(NULL == dir)
    {
        perror("open dir error");
        return -1;
    }
    dirfd2 = dirfd(dir);
    if(-1 == dirfd2)
    {
        perror("dirfd error");
        return -1;
    }
 
    fd = openat(dirfd2,"output.log",O_CREAT|O_RDWR|O_TRUNC);
    if(-1 == fd)
    {
        perror("opeat error");
        return -1;
    }
    n = write(fd,"Hello world!\n",15);
    
    close(fd);
    closedir(dir);
 
    return 0;
}

추천

출처www.cnblogs.com/schips/p/12504846.html