UNIX文件描述符

Unix file descriptor

本文关键字:描述 文件 UNIX      更新时间:2023-10-16

今天,我在Linux中发现了文件描述符的非常有趣的行为。查看该代码:

#include <dirent.h>     /* Defines DT_* constants */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <errno.h>

#define handle_error(msg) 
do { trace(msg); exit(0); } while (0)
#define trace printf
int createFile(const char* name) {
    int r;
    r = ::open( name, 0 );
    if (r < 0)
    {
        trace("create file : %sn", name);
        r = ::open( name, O_CREAT, 0666 );
        if (r < 0)
            trace("error r < 0 %dn",errno);
    }
    return r;
}
int createDir(const char* name) {
    int r = ::mkdir( name, 0777 );
    if (r != 0) {
        trace("error r!=0n");
    }
    r = open(name, 0);
    if (r < 0) {
        trace("error create dir r <0n");
    }
    return r;
}
struct linux_dirent {
    long           d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    char           d_name[];
};
#include <sys/types.h>
#include <dirent.h>
void test123(int fd) {
    int nread;
    char buf[1024];
    unsigned char buffer[1024];
    struct linux_dirent *d;
    int bpos,r;
    char d_type;

    if (fd == -1)
        handle_error("open");
    for ( ; ; ) {
        nread = syscall(SYS_getdents, fd, buf, 1024);
        if (nread == -1)
            handle_error("getdents");
        if (nread == 0)
            break;
        trace("--------------- nread=%d ---------------n", nread);
        trace("i-node#  file type  d_reclen  d_off   d_namen");
        for (bpos = 0; bpos < nread;) {
            d = (struct linux_dirent *) (buf + bpos);
            trace("%8ld  ", d->d_ino);
            d_type = *(buf + bpos + d->d_reclen - 1);
            trace("%4d %10lld  %sn", d->d_reclen,
                  (long long) d->d_off, d->d_name);
            bpos += d->d_reclen;
        }
    }
}

int main(int argc, const char * argv[]) {

    int dir = createDir("test");
    int file = createFile("test/file.gg");
    test123(dir);
    close(dir);
    close(file);

    return 0;
}

在该代码中,我创建文件夹,保存其文件描述符,在该文件夹中创建文件,以及我想通过文件描述符在该目录中打印所有文件之后。但是我得到了这个输出:

create file : test/file.gg
--------------- nread=32 ---------------
i-node#  file type  d_reclen  d_off   d_name
   48879    16          1  .
   48880    16          2  ..

该文件夹中没有file.gg文件。因此,我的问题是 - 如何以及如何与文件描述符正确工作?据我了解,文件描述符只是包含所有打开文件和目录的过程表的本地索引。但是看起来,该文件夹描述符在该文件夹中以某种方式缓存文件。在我的情况下,如何与描述符正确工作?

尝试在您的目录上执行fsync。您应该使用O_RDonly标志打开目录。O_Wronly将失败。创建文件,同步可能不会同步此文件。本文的更多信息