summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/dirent
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libc-top-half/musl/src/dirent/__dirent.h11
-rw-r--r--libc-top-half/musl/src/dirent/alphasort.c9
-rw-r--r--libc-top-half/musl/src/dirent/closedir.c11
-rw-r--r--libc-top-half/musl/src/dirent/dirfd.c7
-rw-r--r--libc-top-half/musl/src/dirent/fdopendir.c31
-rw-r--r--libc-top-half/musl/src/dirent/opendir.c21
-rw-r--r--libc-top-half/musl/src/dirent/readdir.c29
-rw-r--r--libc-top-half/musl/src/dirent/readdir_r.c29
-rw-r--r--libc-top-half/musl/src/dirent/rewinddir.c13
-rw-r--r--libc-top-half/musl/src/dirent/scandir.c47
-rw-r--r--libc-top-half/musl/src/dirent/seekdir.c12
-rw-r--r--libc-top-half/musl/src/dirent/telldir.c7
-rw-r--r--libc-top-half/musl/src/dirent/versionsort.c11
13 files changed, 238 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/dirent/__dirent.h b/libc-top-half/musl/src/dirent/__dirent.h
new file mode 100644
index 0000000..828a5f1
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/__dirent.h
@@ -0,0 +1,11 @@
+struct __dirstream
+{
+ off_t tell;
+ int fd;
+ int buf_pos;
+ int buf_end;
+ volatile int lock[1];
+ /* Any changes to this struct must preserve the property:
+ * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */
+ char buf[2048];
+};
diff --git a/libc-top-half/musl/src/dirent/alphasort.c b/libc-top-half/musl/src/dirent/alphasort.c
new file mode 100644
index 0000000..bee672e
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/alphasort.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <dirent.h>
+
+int alphasort(const struct dirent **a, const struct dirent **b)
+{
+ return strcoll((*a)->d_name, (*b)->d_name);
+}
+
+weak_alias(alphasort, alphasort64);
diff --git a/libc-top-half/musl/src/dirent/closedir.c b/libc-top-half/musl/src/dirent/closedir.c
new file mode 100644
index 0000000..e794ae9
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/closedir.c
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "__dirent.h"
+
+int closedir(DIR *dir)
+{
+ int ret = close(dir->fd);
+ free(dir);
+ return ret;
+}
diff --git a/libc-top-half/musl/src/dirent/dirfd.c b/libc-top-half/musl/src/dirent/dirfd.c
new file mode 100644
index 0000000..6c86007
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/dirfd.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+int dirfd(DIR *d)
+{
+ return d->fd;
+}
diff --git a/libc-top-half/musl/src/dirent/fdopendir.c b/libc-top-half/musl/src/dirent/fdopendir.c
new file mode 100644
index 0000000..d78fb87
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/fdopendir.c
@@ -0,0 +1,31 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "__dirent.h"
+
+DIR *fdopendir(int fd)
+{
+ DIR *dir;
+ struct stat st;
+
+ if (fstat(fd, &st) < 0) {
+ return 0;
+ }
+ if (fcntl(fd, F_GETFL) & O_PATH) {
+ errno = EBADF;
+ return 0;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ return 0;
+ }
+ if (!(dir = calloc(1, sizeof *dir))) {
+ return 0;
+ }
+
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ dir->fd = fd;
+ return dir;
+}
diff --git a/libc-top-half/musl/src/dirent/opendir.c b/libc-top-half/musl/src/dirent/opendir.c
new file mode 100644
index 0000000..5cb84e3
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/opendir.c
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "__dirent.h"
+#include "syscall.h"
+
+DIR *opendir(const char *name)
+{
+ int fd;
+ DIR *dir;
+
+ if ((fd = open(name, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
+ return 0;
+ if (!(dir = calloc(1, sizeof *dir))) {
+ __syscall(SYS_close, fd);
+ return 0;
+ }
+ dir->fd = fd;
+ return dir;
+}
diff --git a/libc-top-half/musl/src/dirent/readdir.c b/libc-top-half/musl/src/dirent/readdir.c
new file mode 100644
index 0000000..569fc70
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/readdir.c
@@ -0,0 +1,29 @@
+#include <dirent.h>
+#include <errno.h>
+#include <stddef.h>
+#include "__dirent.h"
+#include "syscall.h"
+
+typedef char dirstream_buf_alignment_check[1-2*(int)(
+ offsetof(struct __dirstream, buf) % sizeof(off_t))];
+
+struct dirent *readdir(DIR *dir)
+{
+ struct dirent *de;
+
+ if (dir->buf_pos >= dir->buf_end) {
+ int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
+ if (len <= 0) {
+ if (len < 0 && len != -ENOENT) errno = -len;
+ return 0;
+ }
+ dir->buf_end = len;
+ dir->buf_pos = 0;
+ }
+ de = (void *)(dir->buf + dir->buf_pos);
+ dir->buf_pos += de->d_reclen;
+ dir->tell = de->d_off;
+ return de;
+}
+
+weak_alias(readdir, readdir64);
diff --git a/libc-top-half/musl/src/dirent/readdir_r.c b/libc-top-half/musl/src/dirent/readdir_r.c
new file mode 100644
index 0000000..e2a818f
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/readdir_r.c
@@ -0,0 +1,29 @@
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include "__dirent.h"
+#include "lock.h"
+
+int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **restrict result)
+{
+ struct dirent *de;
+ int errno_save = errno;
+ int ret;
+
+ LOCK(dir->lock);
+ errno = 0;
+ de = readdir(dir);
+ if ((ret = errno)) {
+ UNLOCK(dir->lock);
+ return ret;
+ }
+ errno = errno_save;
+ if (de) memcpy(buf, de, de->d_reclen);
+ else buf = NULL;
+
+ UNLOCK(dir->lock);
+ *result = buf;
+ return 0;
+}
+
+weak_alias(readdir_r, readdir64_r);
diff --git a/libc-top-half/musl/src/dirent/rewinddir.c b/libc-top-half/musl/src/dirent/rewinddir.c
new file mode 100644
index 0000000..7ddda43
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/rewinddir.c
@@ -0,0 +1,13 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "lock.h"
+
+void rewinddir(DIR *dir)
+{
+ LOCK(dir->lock);
+ lseek(dir->fd, 0, SEEK_SET);
+ dir->buf_pos = dir->buf_end = 0;
+ dir->tell = 0;
+ UNLOCK(dir->lock);
+}
diff --git a/libc-top-half/musl/src/dirent/scandir.c b/libc-top-half/musl/src/dirent/scandir.c
new file mode 100644
index 0000000..7ee195d
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/scandir.c
@@ -0,0 +1,47 @@
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stddef.h>
+
+int scandir(const char *path, struct dirent ***res,
+ int (*sel)(const struct dirent *),
+ int (*cmp)(const struct dirent **, const struct dirent **))
+{
+ DIR *d = opendir(path);
+ struct dirent *de, **names=0, **tmp;
+ size_t cnt=0, len=0;
+ int old_errno = errno;
+
+ if (!d) return -1;
+
+ while ((errno=0), (de = readdir(d))) {
+ if (sel && !sel(de)) continue;
+ if (cnt >= len) {
+ len = 2*len+1;
+ if (len > SIZE_MAX/sizeof *names) break;
+ tmp = realloc(names, len * sizeof *names);
+ if (!tmp) break;
+ names = tmp;
+ }
+ names[cnt] = malloc(de->d_reclen);
+ if (!names[cnt]) break;
+ memcpy(names[cnt++], de, de->d_reclen);
+ }
+
+ closedir(d);
+
+ if (errno) {
+ if (names) while (cnt-->0) free(names[cnt]);
+ free(names);
+ return -1;
+ }
+ errno = old_errno;
+
+ if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
+ *res = names;
+ return cnt;
+}
+
+weak_alias(scandir, scandir64);
diff --git a/libc-top-half/musl/src/dirent/seekdir.c b/libc-top-half/musl/src/dirent/seekdir.c
new file mode 100644
index 0000000..bf6cc6e
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/seekdir.c
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "lock.h"
+
+void seekdir(DIR *dir, long off)
+{
+ LOCK(dir->lock);
+ dir->tell = lseek(dir->fd, off, SEEK_SET);
+ dir->buf_pos = dir->buf_end = 0;
+ UNLOCK(dir->lock);
+}
diff --git a/libc-top-half/musl/src/dirent/telldir.c b/libc-top-half/musl/src/dirent/telldir.c
new file mode 100644
index 0000000..cf25acf
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/telldir.c
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+long telldir(DIR *dir)
+{
+ return dir->tell;
+}
diff --git a/libc-top-half/musl/src/dirent/versionsort.c b/libc-top-half/musl/src/dirent/versionsort.c
new file mode 100644
index 0000000..d4c4892
--- /dev/null
+++ b/libc-top-half/musl/src/dirent/versionsort.c
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <dirent.h>
+
+int versionsort(const struct dirent **a, const struct dirent **b)
+{
+ return strverscmp((*a)->d_name, (*b)->d_name);
+}
+
+#undef versionsort64
+weak_alias(versionsort, versionsort64);