[LINUX] [C language] readdir () vs readdir_r ()

readdir() vs readdir_r()

As a function to read a directory readdir() / readdir_r()Two functions are provided by the standard library.

If you are using single thread, you can use `readdir ()`, but If you use `readdir_r ()` which is thread-safe for multithreading It is reasonable to think that it is good.

In conclusion, `readdir_r ()` should not be used. In the case of multithreading, it is better to use `readdir () + exclusive control`.

readdir () specifications for readdir_r ()

Let's see why this is the case. First, check the specifications of readdir () and readdir_r ().

Specifications of readdir () (POSIX.1-2008)

POSIX.1-2008 states that the thread safety of `readdir ()` is not guaranteed.

DESCRIPTION The readdir() function need not be thread-safe.

Reference: readdir, readdir_r --read a directory

2.9.1 Thread-Safety All functions defined by this volume of POSIX.1-2017 shall be thread-safe, except that the following functions1 need not be thread-safe. readdir()

Reference: The Open Group Base Specifications Issue 7, 2018 edition --2.9.1 Thread-Safety

specifications of readdir_r ()

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

readdir_r()Reads the next directory entry from the directory stream dirp The entry is stored and returned in the buffer allocated by the caller pointed to by the entry. A pointer to the returned entry is stored in * result. When the end of the directory stream is reached, NULL is stored in * result.

In Linux, the dirent structure is defined as follows.

struct dirent {  
 ino_t d_ino; /* inode number */  
 off_t d_off; /* not an offset; see NOTES */  
 unsigned short d_reclen; /* length of this record */  
 unsigned char d_type; /* type of file; not supported by all file system types */  
 char d_name[256]; /* filename */  
};

Problems caused by ambiguity in POSIX.1.

POSIX.1 does not specify the size of the d_name field (* 1) There may be other non-standard fields after d_name in the dirent struct, so If you use readdir_r () in a portable application, pass the buffer to entry It should be assigned as follows:

name_max = pathconf(dirpath, _PC_NAME_MAX);  
if (name_max == -1) /* Limit not defined, or error */  
 name_max = 255; /* Take a guess */  
 len = offsetof(struct dirent, d_name) + name_max + 1;  
 entryp = malloc(len);  

(* 1) In Solaris, d_name is defined as d_name [1].

However, this above measure is due to the ambiguity of the _PC_NAME_MAX constant definition. It has been pointed out that it will lead to buffer overflow.

Linux / glibc side view

In the current POSIX.1 specification (POSIX.1-2008), readdir() is not required to be thread-safe. However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function. It is expected that a future version of POSIX.1 will require that readdir() be thread- safe when concurrently employed on different directory streams.

Reference: readdir (3) --Linux manual page

readdir_r () / readdir64_r () is deprecated in glibc 2.24

Also, readdir_r () and readdir64_r () have been deprecated in glibc 2.24.

  • The readdir_r and readdir64_r functions have been deprecated. It is recommended to use readdir and readdir64 instead.

Reference: Adhemerval Zanella --The GNU C Library version 2.24 is now available

Conclusion

From the above, instead of using `readdir_r ()` even in multithreading, readdir() +exclusion controlShould be considered for use.

reference

http://mkosaki.blog46.fc2.com/blog-entry-1237.html http://blog.gachapin-sensei.com/archives/618834.html

Recommended Posts

[C language] readdir () vs readdir_r ()
C language ALDS1_3_B Queue
[C language algorithm] Endianness
Machine language embedding in C language
C language ALDS1_4_B Binary Search
PyTorch C ++ VS Python (2019 Edition)
C language ALDS1_4_A Linear Search
Multi-instance module test in C language
Function pointer and objdump ~ C language ~
Realize interface class in C language
Writing C language with Sympy (metaprogramming)
High energy efficiency programming language C
Introduction to Protobuf-c (C language ⇔ Python)
[C language algorithm] Binary search tree
C language 8 queens problem solving 3 patterns
Segfault with 16 characters in C language
Call c language from python (python.h)