From 2287b1e29b3d08538bd4e1757550ce3475f6a9e4 Mon Sep 17 00:00:00 2001 From: turbocat Date: Wed, 2 Jun 2021 00:58:56 +0000 Subject: [PATCH] newlibc: Added new functions: - dir.h: mkdir, rmdir, chdir - dirent.h: alphasort, opendir, closedir, readdir, rewinddir, seekdir, telldir, scandir git-svn-id: svn://kolibrios.org@8759 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/sdk/sources/newlib/libc/Makefile | 18 ++- contrib/sdk/sources/newlib/libc/Tupfile.lua | 12 ++ .../sources/newlib/libc/dirent/alphasort.c | 7 ++ .../sdk/sources/newlib/libc/dirent/closedir.c | 14 +++ contrib/sdk/sources/newlib/libc/dirent/dir.c | 16 +++ .../sdk/sources/newlib/libc/dirent/ksys_fs.h | 110 ++++++++++++++++++ .../sdk/sources/newlib/libc/dirent/opendir.c | 53 +++++++++ .../sdk/sources/newlib/libc/dirent/readdir.c | 14 +++ .../sources/newlib/libc/dirent/rewinddir.c | 9 ++ .../sdk/sources/newlib/libc/dirent/scandir.c | 46 ++++++++ .../sdk/sources/newlib/libc/dirent/seekdir.c | 12 ++ .../sdk/sources/newlib/libc/dirent/telldir.c | 12 ++ .../sdk/sources/newlib/libc/include/sys/dir.h | 4 + .../sources/newlib/libc/include/sys/dirent.h | 41 ++++--- contrib/sdk/sources/newlib/libc/libc.def | 11 ++ 15 files changed, 360 insertions(+), 19 deletions(-) create mode 100644 contrib/sdk/sources/newlib/libc/dirent/alphasort.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/closedir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/dir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/ksys_fs.h create mode 100644 contrib/sdk/sources/newlib/libc/dirent/opendir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/readdir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/rewinddir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/scandir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/seekdir.c create mode 100644 contrib/sdk/sources/newlib/libc/dirent/telldir.c diff --git a/contrib/sdk/sources/newlib/libc/Makefile b/contrib/sdk/sources/newlib/libc/Makefile index e83bf16fb0..c6787cdac0 100644 --- a/contrib/sdk/sources/newlib/libc/Makefile +++ b/contrib/sdk/sources/newlib/libc/Makefile @@ -2,7 +2,7 @@ CC = kos32-gcc AR = kos32-ar LD = kos32-ld -INSTALLDIR:= /home/autobuild/tools/win32/lib +INSTALLDIR:= /home/autobuild/tools/win32/mingw32 CFLAGS = -c -O2 -fno-builtin -fno-ident -fomit-frame-pointer -DMISSING_SYSCALL_NAMES LDFLAGS = -shared -s -T libcdll.lds --out-implib libc.dll.a --image-base 0 @@ -472,6 +472,15 @@ STDIO_SRCS= \ wscanf.c \ wsetup.c +DIRENT_SRCS= dir.c \ + closedir.c \ + opendir.c \ + readdir.c \ + rewinddir.c \ + seekdir.c \ + telldir.c \ + scandir.c \ + alphasort.c MATH_SRCS = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c e_exp.c e_fmod.c \ e_hypot.c e_j0.c e_j1.c e_jn.c e_log.c e_log10.c e_pow.c e_rem_pio2.c \ @@ -529,6 +538,8 @@ STRING_OBJS = $(patsubst %.S, string/%.o, $(patsubst %.asm, string/%.o,\ STDLIB_OBJS = $(patsubst %.S, stdlib/%.o, $(patsubst %.asm, stdlib/%.o,\ $(patsubst %.c, stdlib/%.o, $(STDLIB_SRCS)))) +DIRENT_OBJS = $(patsubst %.S, dirent/%.o, $(patsubst %.asm, dirent/%.o,\ + $(patsubst %.c, dirent/%.o, $(DIRENT_SRCS)))) MATH_OBJS = $(patsubst %.S, math/%.o, $(patsubst %.asm, math/%.o,\ $(patsubst %.c, math/%.o, $(MATH_SRCS)))) @@ -573,7 +584,8 @@ LIB_OBJS+= \ $(STDLIB_OBJS) \ $(STDIO_OBJS) \ $(PRINTF_OBJS) \ - $(MATH_OBJS) + $(MATH_OBJS) \ + $(DIRENT_OBJS) LIB_OBJS+= time/wcsftime.o @@ -662,7 +674,7 @@ time/wcsftime.o: time/strftime.c %.obj : %.asm Makefile - fasm $< $ + fasm $< %.o : %.c Makefile $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $< diff --git a/contrib/sdk/sources/newlib/libc/Tupfile.lua b/contrib/sdk/sources/newlib/libc/Tupfile.lua index 0a589ddfe8..9b4a8b3667 100644 --- a/contrib/sdk/sources/newlib/libc/Tupfile.lua +++ b/contrib/sdk/sources/newlib/libc/Tupfile.lua @@ -454,6 +454,17 @@ STDIO_SRCS = { "wsetup.c" } +DIRENT_SRCS = { + "dir.c", + "closedir.c", + "opendir.c", + "readdir.c", + "rewinddir.c", + "seekdir.c", + "telldir.c", + "scandir.c", + "alphasort.c", +} MATH_SRCS = { "e_acos.c", "e_acosh.c", "e_asin.c", "e_atan2.c", "e_atanh.c", "e_cosh.c", "e_exp.c", "e_fmod.c", @@ -506,6 +517,7 @@ LIB_SRCS += CORE_SRCS LIB_SRCS += prepend("stdio/", STDIO_SRCS) LIB_SRCS += prepend("string/", STRING_SRCS) LIB_SRCS += prepend("stdlib/", STDLIB_SRCS) +LIB_SRCS += prepend("dirent/", DIRENT_SRCS) LIB_SRCS += prepend("math/", MATH_SRCS) ALL_OBJS = {} diff --git a/contrib/sdk/sources/newlib/libc/dirent/alphasort.c b/contrib/sdk/sources/newlib/libc/dirent/alphasort.c new file mode 100644 index 0000000000..826ddae25b --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/alphasort.c @@ -0,0 +1,7 @@ +#include +#include + +int alphasort(const struct dirent **a, const struct dirent **b) +{ + return strcoll((*a)->d_name, (*b)->d_name); +} diff --git a/contrib/sdk/sources/newlib/libc/dirent/closedir.c b/contrib/sdk/sources/newlib/libc/dirent/closedir.c new file mode 100644 index 0000000000..9dcca25f44 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/closedir.c @@ -0,0 +1,14 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include +#include + +int closedir(DIR *dir){ + if(dir == NULL){ + return -1; + }else{ + free(dir->objs); + free(dir); + return 0; + } +} \ No newline at end of file diff --git a/contrib/sdk/sources/newlib/libc/dirent/dir.c b/contrib/sdk/sources/newlib/libc/dirent/dir.c new file mode 100644 index 0000000000..6c31c68d28 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/dir.c @@ -0,0 +1,16 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include "ksys_fs.h" + +int rmdir(const char* dir){ + return _ksys_file_delete(dir); +} + +int mkdir(const char* dir, unsigned fake_mode){ + return _ksys_mkdir(dir); +} + +int chdir(char* dir){ + _ksys_setcwd(dir); + return 0; +} \ No newline at end of file diff --git a/contrib/sdk/sources/newlib/libc/dirent/ksys_fs.h b/contrib/sdk/sources/newlib/libc/dirent/ksys_fs.h new file mode 100644 index 0000000000..410a9d7d13 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/ksys_fs.h @@ -0,0 +1,110 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#ifndef _KSYS_FS_H_ +#define _KSYS_FS_H_ + +#include +#include + +#define asm_inline __asm__ __volatile__ + +#pragma pack(push,1) +typedef struct{ + unsigned p00; + union{ + uint64_t p04; + struct { + unsigned p04dw; + unsigned p08dw; + }; + }; + unsigned p12; + union { + unsigned p16; + const char *new_name; + void *bdfe; + void *buf16; + const void *cbuf16; + }; + char p20; + const char *p21; +}ksys70_t; + +typedef struct { + unsigned attributes; + unsigned name_cp; + char creation_time[4]; + char creation_date[4]; + char last_access_time[4]; + char last_access_date[4]; + char last_modification_time[4]; + char last_modification_date[4]; + unsigned long long size; + char name[0]; +}ksys_bdfe_t; +#pragma pack(pop) + +static inline +int _ksys_work_files(const ksys70_t *k) +{ + int status; + asm_inline( + "int $0x40" + :"=a"(status) + :"a"(70), "b"(k) + :"memory" + ); + return status; +} + +static inline +int _ksys_file_delete(const char *name) +{ + ksys70_t k; + k.p00 = 8; + k.p20 = 0; + k.p21 = name; + return _ksys_work_files(&k); +} + +static inline +int _ksys_mkdir(const char *path) +{ + ksys70_t dir_opt; + dir_opt.p00 = 9; + dir_opt.p21 = path; + return _ksys_work_files(&dir_opt); +} + +static inline +void _ksys_setcwd(char* dir){ + asm_inline( + "int $0x40" + ::"a"(30), "b"(1), "c"(dir) + ); +} + +static inline +void* _ksys_alloc(size_t size){ + void *val; + asm_inline( + "int $0x40" + :"=a"(val) + :"a"(68),"b"(12),"c"(size) + ); + return val; +} + +static inline +int _ksys_free(void *mem) +{ + int val; + asm_inline( + "int $0x40" + :"=a"(val) + :"a"(68),"b"(13),"c"(mem) + ); + return val; +} + +#endif diff --git a/contrib/sdk/sources/newlib/libc/dirent/opendir.c b/contrib/sdk/sources/newlib/libc/dirent/opendir.c new file mode 100644 index 0000000000..ba40c4eacf --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/opendir.c @@ -0,0 +1,53 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include +#include "ksys_fs.h" +#include +#include +#include + +#define CHECK_DIR_ERR() if(_ksys_work_files(&inf)){ \ + free((void*)inf.p16); \ + errno = ENOTDIR; \ + return NULL; \ + } + +DIR* opendir(const char* path) +{ + DIR* list = malloc(sizeof(DIR)); + if(list==NULL){ + errno = ENOMEM; + return NULL; + } + + list->pos=0; + unsigned num_of_file=0; + static ksys70_t inf; + + inf.p00 = 1; + inf.p04 = 0; + inf.p12 = 2; + inf.p16 = (unsigned) malloc(32+inf.p12*560); + inf.p20 = 0; + inf.p21 = (char*)path; + + CHECK_DIR_ERR(); + + num_of_file = *(unsigned*)(inf.p16+8); + inf.p12 = num_of_file; + free((void*)inf.p16); + inf.p16 = (unsigned)_ksys_alloc(32+inf.p12*560); + list->objs = (struct dirent*) malloc(num_of_file*sizeof(struct dirent)); + + CHECK_DIR_ERR(); + + for(int i=0; iobjs[i].d_ino = i; + list->objs[i].d_type = *(unsigned*)(inf.p16+32+(264+40)*i); + strcpy(list->objs[i].d_name,(char*)(inf.p16+32+40+(264+40)*i)); + } + list->num_objs = num_of_file; + return list; +} + + diff --git a/contrib/sdk/sources/newlib/libc/dirent/readdir.c b/contrib/sdk/sources/newlib/libc/dirent/readdir.c new file mode 100644 index 0000000000..e5e68dbcdd --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/readdir.c @@ -0,0 +1,14 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include +#include + +struct dirent* readdir(DIR *dir) +{ + if(dir->num_objs>dir->pos){ + dir->pos++; + return &dir->objs[dir->pos-1]; + }else{ + return NULL; + } +} diff --git a/contrib/sdk/sources/newlib/libc/dirent/rewinddir.c b/contrib/sdk/sources/newlib/libc/dirent/rewinddir.c new file mode 100644 index 0000000000..3fc549857b --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/rewinddir.c @@ -0,0 +1,9 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include + +void rewinddir(DIR *dir){ + if(dir!=NULL){ + dir->pos=0; + } +} \ No newline at end of file diff --git a/contrib/sdk/sources/newlib/libc/dirent/scandir.c b/contrib/sdk/sources/newlib/libc/dirent/scandir.c new file mode 100644 index 0000000000..79a16bb885 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/scandir.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +#define SIZE_MAX 256 + +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(sizeof(struct dirent)); + if (!names[cnt]) break; + memcpy(names[cnt++], de, sizeof(struct dirent)); + } + + 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; +} diff --git a/contrib/sdk/sources/newlib/libc/dirent/seekdir.c b/contrib/sdk/sources/newlib/libc/dirent/seekdir.c new file mode 100644 index 0000000000..cb6c8e9463 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/seekdir.c @@ -0,0 +1,12 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include + +void seekdir(DIR *dir, unsigned pos) +{ + if(dir==NULL || pos>dir->num_objs){ + return; + } + dir->pos=pos; + return; +} \ No newline at end of file diff --git a/contrib/sdk/sources/newlib/libc/dirent/telldir.c b/contrib/sdk/sources/newlib/libc/dirent/telldir.c new file mode 100644 index 0000000000..e3647a47c5 --- /dev/null +++ b/contrib/sdk/sources/newlib/libc/dirent/telldir.c @@ -0,0 +1,12 @@ +/* Copyright (C) 2021 Logaev Maxim (turbocat2001), GPLv2 */ + +#include + +unsigned telldir(DIR *dir) +{ + if(dir!=NULL){ + return dir->pos; + }else{ + return 0; + } +} \ No newline at end of file diff --git a/contrib/sdk/sources/newlib/libc/include/sys/dir.h b/contrib/sdk/sources/newlib/libc/include/sys/dir.h index 11a8c648c9..0fe67360fe 100644 --- a/contrib/sdk/sources/newlib/libc/include/sys/dir.h +++ b/contrib/sdk/sources/newlib/libc/include/sys/dir.h @@ -7,4 +7,8 @@ #define direct dirent +extern int chdir(char* dir); +extern int rmdir(const char* dir); +extern int mkdir(const char* dir, unsigned fake_mode); + #endif /*_SYS_DIR_H_*/ diff --git a/contrib/sdk/sources/newlib/libc/include/sys/dirent.h b/contrib/sdk/sources/newlib/libc/include/sys/dirent.h index 3e3c122488..81107c9d56 100644 --- a/contrib/sdk/sources/newlib/libc/include/sys/dirent.h +++ b/contrib/sdk/sources/newlib/libc/include/sys/dirent.h @@ -8,24 +8,33 @@ extern "C" { #endif -struct dirent { - char d_namlen; - char d_name[256]; +#define DT_DIR 16 +#define DT_REG 0 + +#include +#include + +struct dirent{ + ino_t d_ino; + unsigned d_type; + char d_name[256]; }; + +typedef struct{ + struct dirent* objs; + ino_t pos; + ino_t num_objs; +}DIR; + +extern int closedir(DIR *dir); +extern DIR* opendir(const char *path); +extern struct dirent* readdir(DIR *); +extern void rewinddir(DIR *dir); +extern void seekdir(DIR *dir, unsigned pos); +extern unsigned telldir(DIR *dir); -typedef struct -{ -// struct systree_info2 fileinfo; - struct dirent entry; -// __u8 bdfeheader[0x20]; -// struct bdfe_item bdfebase; -// __u8 bdfename[264]; -} DIR; - -int closedir(DIR *dirp); -DIR * opendir(const char *_dirname); -struct dirent * readdir(DIR *_dirp); -void rewinddir(DIR *_dirp); +extern int scandir(const char *path, struct dirent ***res, int (*sel)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)); +extern int alphasort(const struct dirent **a, const struct dirent **b); #ifdef __cplusplus } diff --git a/contrib/sdk/sources/newlib/libc/libc.def b/contrib/sdk/sources/newlib/libc/libc.def index c0f51311d7..b63cd54fe9 100644 --- a/contrib/sdk/sources/newlib/libc/libc.def +++ b/contrib/sdk/sources/newlib/libc/libc.def @@ -507,3 +507,14 @@ EXPORTS y1f yn ynf + alphasort + opendir + closedir + readdir + rewinddir + seekdir + telldir + scandir + mkdir + rmdir + chdir