]> git.saurik.com Git - apple/libc.git/blob - gen/readdir_r.c
8e19cccfc252514ea2b24d3b6d7e8106e57b6d56
[apple/libc.git] / gen / readdir_r.c
1 #include <sys/types.h>
2 #include <dirent.h>
3 #include <pthread.h>
4
5 /*
6 * Synopsis:
7 * dir_table is a global static array of pthread mutexes. The array is NMUTEXES
8 * in length (NMUTEXES * sizeof(pthread_mutex_t)).
9 *
10 * Whenever a call to readdir_r is made, the element in the array indexed by the
11 * modulus of the file descriptor associated with dirp is locked, and readdir is
12 * called on dirp. The result is returned in readdir_r semantics and the
13 * element in dir_table is unlocked.
14 */
15
16 static pthread_mutex_t dir_table[] = {
17 PTHREAD_MUTEX_INITIALIZER,
18 PTHREAD_MUTEX_INITIALIZER,
19 PTHREAD_MUTEX_INITIALIZER,
20 PTHREAD_MUTEX_INITIALIZER,
21 PTHREAD_MUTEX_INITIALIZER,
22 PTHREAD_MUTEX_INITIALIZER,
23 PTHREAD_MUTEX_INITIALIZER,
24 PTHREAD_MUTEX_INITIALIZER
25 #define NMUTEXES 8
26 };
27
28 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
29 {
30 int ret;
31 int mindex = dirp->dd_fd % NMUTEXES;
32 struct dirent *tmpdp;
33
34 pthread_mutex_lock(&dir_table[mindex]);
35
36 tmpdp = readdir(dirp);
37 if( tmpdp == NULL ) {
38 *result = NULL;
39 ret = errno;
40 pthread_mutex_unlock(&dir_table[mindex]);
41 return ret;
42 }
43
44 memcpy(entry, tmpdp, sizeof(struct dirent));
45 *result = entry;
46
47 pthread_mutex_unlock(&dir_table[mindex]);
48 return 0;
49 }
50
51