X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/3b2a1fe8d3d02703ddca1b0ead469074d4e47820..5b2abdfbf4211b6592cdd02b9507555a0ecbb04b:/gen/readdir_r.c?ds=inline diff --git a/gen/readdir_r.c b/gen/readdir_r.c new file mode 100644 index 0000000..8e19ccc --- /dev/null +++ b/gen/readdir_r.c @@ -0,0 +1,51 @@ +#include +#include +#include + +/* + * Synopsis: + * dir_table is a global static array of pthread mutexes. The array is NMUTEXES + * in length (NMUTEXES * sizeof(pthread_mutex_t)). + * + * Whenever a call to readdir_r is made, the element in the array indexed by the + * modulus of the file descriptor associated with dirp is locked, and readdir is + * called on dirp. The result is returned in readdir_r semantics and the + * element in dir_table is unlocked. + */ + +static pthread_mutex_t dir_table[] = { + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER +#define NMUTEXES 8 +}; + +int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +{ + int ret; + int mindex = dirp->dd_fd % NMUTEXES; + struct dirent *tmpdp; + + pthread_mutex_lock(&dir_table[mindex]); + + tmpdp = readdir(dirp); + if( tmpdp == NULL ) { + *result = NULL; + ret = errno; + pthread_mutex_unlock(&dir_table[mindex]); + return ret; + } + + memcpy(entry, tmpdp, sizeof(struct dirent)); + *result = entry; + + pthread_mutex_unlock(&dir_table[mindex]); + return 0; +} + +