mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-30 00:07:59 +00:00
userspace/libc: implement alphasort, fdopendir, opendir, posix_getdents, readdir & scandir
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
d0a8d9dd62
commit
92ef18b412
@ -58,16 +58,16 @@ extern "C"
|
|||||||
#define DT_SHM
|
#define DT_SHM
|
||||||
#define DT_TMO
|
#define DT_TMO
|
||||||
|
|
||||||
int alphasort(const struct dirent **, const struct dirent **);
|
int alphasort(const struct dirent **d1, const struct dirent **d2);
|
||||||
int closedir(DIR *dirp);
|
int closedir(DIR *dirp);
|
||||||
int dirfd(DIR *dirp);
|
int dirfd(DIR *dirp);
|
||||||
DIR *fdopendir(int);
|
DIR *fdopendir(int fd);
|
||||||
DIR *opendir(const char *);
|
DIR *opendir(const char *dirname);
|
||||||
ssize_t posix_getdents(int, void *, size_t, int);
|
ssize_t posix_getdents(int fildes, void *buf, size_t nbyte, int flags);
|
||||||
struct dirent *readdir(DIR *);
|
struct dirent *readdir(DIR *dirp);
|
||||||
int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
|
int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
|
||||||
void rewinddir(DIR *);
|
void rewinddir(DIR *);
|
||||||
int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
|
int scandir(const char *dir, struct dirent ***namelist, int (*sel)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
|
||||||
void seekdir(DIR *, long);
|
void seekdir(DIR *, long);
|
||||||
long telldir(DIR *);
|
long telldir(DIR *);
|
||||||
|
|
||||||
|
@ -20,8 +20,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
export int alphasort(const struct dirent **, const struct dirent **);
|
export int alphasort(const struct dirent **d1, const struct dirent **d2)
|
||||||
|
{
|
||||||
|
return strcoll((*d1)->d_name, (*d2)->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
export int closedir(DIR *dirp)
|
export int closedir(DIR *dirp)
|
||||||
{
|
{
|
||||||
@ -52,12 +57,122 @@ export int dirfd(DIR *dirp)
|
|||||||
return __check_errno(-ENOSYS, -1);
|
return __check_errno(-ENOSYS, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export DIR *fdopendir(int);
|
export DIR *fdopendir(int fd)
|
||||||
export DIR *opendir(const char *);
|
{
|
||||||
export ssize_t posix_getdents(int, void *, size_t, int);
|
DIR *dirp = malloc(sizeof(DIR));
|
||||||
export struct dirent *readdir(DIR *);
|
if (dirp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dirp->__fd = fd;
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
export DIR *opendir(const char *dirname)
|
||||||
|
{
|
||||||
|
DIR *dirp = malloc(sizeof(DIR));
|
||||||
|
if (dirp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dirp->__fd = open(dirname, O_RDONLY);
|
||||||
|
if (dirp->__fd == -1)
|
||||||
|
{
|
||||||
|
free(dirp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirp;
|
||||||
|
}
|
||||||
|
|
||||||
|
export ssize_t posix_getdents(int fildes, void *buf, size_t nbyte, int flags)
|
||||||
|
{
|
||||||
|
printf("posix_getdents() is unimplemented\n");
|
||||||
|
return __check_errno(-ENOSYS, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
export struct dirent *readdir(DIR *dirp)
|
||||||
|
{
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *entry = malloc(sizeof(struct dirent));
|
||||||
|
if (entry == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ssize_t bytes = posix_getdents(dirp->__fd, entry, sizeof(struct dirent), 0);
|
||||||
|
if (bytes == -1)
|
||||||
|
{
|
||||||
|
free(entry);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
export int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
|
export int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
|
||||||
export void rewinddir(DIR *);
|
export void rewinddir(DIR *);
|
||||||
export int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
|
|
||||||
|
export int scandir(const char *dir, struct dirent ***namelist, int (*sel)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **))
|
||||||
|
{
|
||||||
|
struct dirent **entry_list = NULL;
|
||||||
|
struct dirent *entry;
|
||||||
|
DIR *dp;
|
||||||
|
int count = 0;
|
||||||
|
int capacity = 10;
|
||||||
|
|
||||||
|
dp = opendir(dir);
|
||||||
|
if (dp == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
entry_list = malloc(capacity * sizeof(struct dirent *));
|
||||||
|
if (entry_list == NULL)
|
||||||
|
{
|
||||||
|
closedir(dp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((entry = readdir(dp)) != NULL)
|
||||||
|
{
|
||||||
|
if (sel == NULL || sel(entry))
|
||||||
|
{
|
||||||
|
if (count >= capacity)
|
||||||
|
{
|
||||||
|
capacity *= 2;
|
||||||
|
struct dirent **new_list = realloc(entry_list, capacity * sizeof(struct dirent *));
|
||||||
|
if (new_list == NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
free(entry_list[i]);
|
||||||
|
free(entry_list);
|
||||||
|
closedir(dp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
entry_list = new_list;
|
||||||
|
}
|
||||||
|
entry_list[count] = malloc(sizeof(struct dirent));
|
||||||
|
if (entry_list[count] == NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
free(entry_list[i]);
|
||||||
|
free(entry_list);
|
||||||
|
closedir(dp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(entry_list[count], entry, sizeof(struct dirent));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dp);
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
qsort(entry_list, count, sizeof(struct dirent *), (int (*)(const void *, const void *))compar);
|
||||||
|
|
||||||
|
*namelist = entry_list;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
export void seekdir(DIR *, long);
|
export void seekdir(DIR *, long);
|
||||||
export long telldir(DIR *);
|
export long telldir(DIR *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user