Unix file descriptor
Today I found very interesting behavior of file descriptors in Linux. Look at this code:
#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 : %s\n", name);
r = ::open( name, O_CREAT, 0666 );
if (r < 0)
trace("error r < 0 %d\n",errno);
}
return r;
}
int createDir(const char* name) {
int r = ::mkdir( name, 0777 );
if (r != 0) {
trace("error r!=0\n");
}
r = open(name, 0);
if (r < 0) {
trace("error create dir r <0\n");
}
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_name\n");
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 %s\n", 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;
}
in this code, I create a folder, store its file descriptor, create a file in that folder and after I want to print all files in that directory via file descriptors. However, I am getting this output:
create file : test/file.gg
--------------- nread=32 ---------------
i-node# file type d_reclen d_off d_name
48879 16 1 .
48880 16 2 ..
There is no file.gg file in this folder. So my question is, how is this and how to work properly with file descriptors? As I understand it, the file descriptor is just an index on the local process table with all files and directories open. But it looks like this folder descriptor is caching some files in this folder. How do I work with descriptors in my case?
source to share
Try fsync in your directory. You must open a directory with O_RDONLY flags. O_WRONLY error. File creation and syncing may not sync the metadata for that file. More information in this article
source to share