]> git.saurik.com Git - apple/libc.git/blobdiff - gen/readdir_r.c
Libc-262.tar.gz
[apple/libc.git] / gen / readdir_r.c
diff --git a/gen/readdir_r.c b/gen/readdir_r.c
new file mode 100644 (file)
index 0000000..8e19ccc
--- /dev/null
@@ -0,0 +1,51 @@
+#include <sys/types.h>
+#include <dirent.h>
+#include <pthread.h>
+
+/*
+ * 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;
+}
+
+