diff options
Diffstat (limited to 'libc-top-half/musl/src/dirent')
-rw-r--r-- | libc-top-half/musl/src/dirent/__dirent.h | 11 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/alphasort.c | 9 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/closedir.c | 11 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/dirfd.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/fdopendir.c | 31 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/opendir.c | 21 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/readdir.c | 29 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/readdir_r.c | 29 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/rewinddir.c | 13 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/scandir.c | 47 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/seekdir.c | 12 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/telldir.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/dirent/versionsort.c | 11 |
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); |