diff options
Diffstat (limited to 'src/libc')
| -rw-r--r-- | src/libc/include/fcntl.h | 13 | ||||
| -rw-r--r-- | src/libc/include/stdio.h | 17 | ||||
| -rw-r--r-- | src/libc/include/stdlib.h | 38 | ||||
| -rw-r--r-- | src/libc/include/sys/stat.h | 32 | ||||
| -rw-r--r-- | src/libc/include/sys/types.h | 1 | ||||
| -rw-r--r-- | src/libc/include/unistd.h | 14 | ||||
| -rw-r--r-- | src/libc/private_include/libc/file.h | 29 | ||||
| -rw-r--r-- | src/libc/src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/libc/src/_putchar.c | 24 | ||||
| -rw-r--r-- | src/libc/src/malloc_init.c | 29 | ||||
| -rw-r--r-- | src/libc/src/ps1/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/libc/src/stdio/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/libc/src/stdio/fopen.c | 95 | ||||
| -rw-r--r-- | src/libc/src/stdio/fputc.c | 40 | ||||
| -rw-r--r-- | src/libc/src/stdio/fwrite.c | 50 | ||||
| -rw-r--r-- | src/libc/src/stdio/putc.c | 25 | ||||
| -rw-r--r-- | src/libc/src/stdio/putchar.c (renamed from src/libc/src/ps1/putchar.c) | 7 | ||||
| -rw-r--r-- | src/libc/src/stdio/streams.c | 24 | ||||
| -rw-r--r-- | src/libc/src/stdlib/malloc.c | 6 | ||||
| -rw-r--r-- | src/libc/src/unistd/sbrk.c | 3 | ||||
| m--------- | src/libc/tinyalloc | 0 |
21 files changed, 413 insertions, 43 deletions
diff --git a/src/libc/include/fcntl.h b/src/libc/include/fcntl.h index 282ced8..1edf2fc 100644 --- a/src/libc/include/fcntl.h +++ b/src/libc/include/fcntl.h @@ -19,11 +19,12 @@ #ifndef _FCNTL_H #define _FCNTL_H -enum -{ - O_RDONLY = 1, - O_WRONLY = 1 << 1, - O_RDWR = O_RDONLY | O_WRONLY -}; +#define O_RDONLY 1 +#define O_WRONLY (1 << 1) +#define O_CREAT (1 << 2) +#define O_APPEND (1 << 3) +#define O_RDWR (O_RDONLY | O_WRONLY) + +int open(const char *__path, int __flags, ...); #endif diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index b9c1a38..efa60dd 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -19,8 +19,23 @@ #ifndef _STDIO_H #define _STDIO_H -enum {EOF = -1}; +#include <stddef.h> +#define BUFSIZ 128 +#define FOPEN_MAX 8 +#define FILENAME_MAX 128 +#define EOF -1 +#define stdin __stdin +#define stdout __stdout +#define stderr __stderr + +typedef struct __file FILE; +extern FILE *__stdin, *__stdout, *__stderr; + +int fputc(int __c, FILE *__f); +FILE *fopen(const char *__path, const char *__mode); +size_t fwrite(const void *__p, size_t __sz, size_t __nmemb, FILE *__f); +int putc(int __c, FILE *__f); int puts(const char *__s); int putchar(int __c); diff --git a/src/libc/include/stdlib.h b/src/libc/include/stdlib.h index 2704fca..b6e092e 100644 --- a/src/libc/include/stdlib.h +++ b/src/libc/include/stdlib.h @@ -57,10 +57,10 @@ div_t div(int __numerator, int __denominator); #define RESET "\x1b[0m" #define malloc(__n) ({void *__p; \ + int Printf(const char *, ...); \ Printf(GREEN "-> %s:%d (%s)", __FILE__, __LINE__, __func__); \ __p = __malloc(__n); \ Printf(", p=%p" RESET "\n", __p); \ - int Printf(const char *, ...); \ size_t ta_num_free(); \ size_t ta_num_used(); \ size_t ta_num_fresh(); \ @@ -71,13 +71,13 @@ div_t div(int __numerator, int __denominator); __p;}) #define realloc(__p, __n) ({void *__np; \ + int Printf(const char *, ...); \ + size_t ta_num_free(); \ + size_t ta_num_used(); \ + size_t ta_num_fresh(); \ Printf(YELLOW "-> %s:%d (%s)", __FILE__, __LINE__, __func__); \ __np = __realloc(__p, __n); \ Printf(", np=%p" RESET "\n", __np); \ - int Printf(const char *, ...); \ - size_t ta_num_free(); \ -size_t ta_num_used(); \ -size_t ta_num_fresh(); \ Printf("%s: free=%lu, used=%lu, fresh=%lu\n", __func__, \ (unsigned long)ta_num_free(), \ (unsigned long)ta_num_used(), \ @@ -85,13 +85,13 @@ size_t ta_num_fresh(); \ __np;}) #define calloc(__n, __sz) ({void *__p; \ + int Printf(const char *, ...); \ + size_t ta_num_free(); \ + size_t ta_num_used(); \ + size_t ta_num_fresh(); \ Printf(YELLOW "-> %s:%d (%s)", __FILE__, __LINE__, __func__); \ __p = __calloc(__n, __sz); \ Printf(", p=%p" RESET "\n", __p); \ - int Printf(const char *, ...); \ - size_t ta_num_free(); \ -size_t ta_num_used(); \ -size_t ta_num_fresh(); \ Printf("%s: free=%lu, used=%lu, fresh=%lu\n", __func__, \ (unsigned long)ta_num_free(), \ (unsigned long)ta_num_used(), \ @@ -100,18 +100,18 @@ size_t ta_num_fresh(); \ #define free(__p) ({ \ int Printf(const char *, ...); \ + size_t ta_num_free(); \ + size_t ta_num_used(); \ + size_t ta_num_fresh(); \ Printf(RED "<- %s:%d (%s), p=%p" RESET "\n", \ __FILE__, __LINE__, __func__, __p); \ - size_t ta_num_free(); \ - size_t ta_num_used(); \ - size_t ta_num_fresh(); \ - __free(__p);\ - Printf("%s: free=%lu, used=%lu, fresh=%lu\n", \ - __func__, \ - (unsigned long)ta_num_free(), \ - (unsigned long)ta_num_used(), \ - (unsigned long)ta_num_fresh()); \ - }) + __free(__p);\ + Printf("%s: free=%lu, used=%lu, fresh=%lu\n", \ + __func__, \ + (unsigned long)ta_num_free(), \ + (unsigned long)ta_num_used(), \ + (unsigned long)ta_num_fresh()); \ + }) #endif #endif diff --git a/src/libc/include/sys/stat.h b/src/libc/include/sys/stat.h index 08fcf9a..b5ef13d 100644 --- a/src/libc/include/sys/stat.h +++ b/src/libc/include/sys/stat.h @@ -22,6 +22,35 @@ #include <sys/types.h> #include <time.h> +#define S_IRWXU 0700 +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define S_IXUSR 0100 +#define S_IRWXG 070 +#define S_IRGRP 040 +#define S_IWGRP 020 +#define S_IXGRP 010 +#define S_IRWXO 07 +#define S_IROTH 04 +#define S_IWOTH 02 +#define S_IXOTH 1 + +#define S_IFBLK ((mode_t)1) +#define S_IFCHR ((mode_t)(1 << 1)) +#define S_IFIFO ((mode_t)(1 << 2)) +#define S_IFREG ((mode_t)(1 << 3)) +#define S_IFDIR ((mode_t)(1 << 4)) +#define S_IFLNK ((mode_t)(1 << 5)) +#define S_IFSOCK ((mode_t)(1 << 6)) + +#define S_ISBLK(__m) ((__m) & S_IFBLK) +#define S_ISCHR(__m) ((__m) & S_IFCHR) +#define S_ISDIR(__m) ((__m) & S_IFDIR) +#define S_ISFIFO(__m) ((__m) & S_IFIFO) +#define S_ISREG(__m) ((__m) & S_IFREG) +#define S_ISLNK(__m) ((__m) & S_IFLNK) +#define S_ISSOCK(__m) ((__m) & S_IFSOCK) + struct stat { dev_t st_dev; @@ -37,6 +66,7 @@ struct stat blkcnt_t st_blocks; }; -int mkdir(const char *pathname, mode_t flags); +int mkdir(const char *__pathname, mode_t __flags); +mode_t umask(mode_t __mask); #endif diff --git a/src/libc/include/sys/types.h b/src/libc/include/sys/types.h index 86ca604..fc231f1 100644 --- a/src/libc/include/sys/types.h +++ b/src/libc/include/sys/types.h @@ -22,5 +22,6 @@ typedef unsigned dev_t, mode_t, nlink_t, uid_t, gid_t, blksize_t, blkcnt_t; typedef unsigned long ino_t, off_t; typedef int pid_t; +typedef long ssize_t; #endif diff --git a/src/libc/include/unistd.h b/src/libc/include/unistd.h index ec4fc13..dcf0336 100644 --- a/src/libc/include/unistd.h +++ b/src/libc/include/unistd.h @@ -19,8 +19,20 @@ #ifndef _UNISTD_H #define _UNISTD_H +#include <stddef.h> #include <stdint.h> +#include <sys/types.h> -void *sbrk(intptr_t increment); +enum +{ + STDIN_FILENO, + STDOUT_FILENO, + STDERR_FILENO +}; + +void *sbrk(intptr_t __increment); +ssize_t read(int __fd, void *__buf, size_t __n); +ssize_t write(int __fd, const void *__buf, size_t __n); +int close(int __fd); #endif diff --git a/src/libc/private_include/libc/file.h b/src/libc/private_include/libc/file.h index dabeb89..8cb3fa0 100644 --- a/src/libc/private_include/libc/file.h +++ b/src/libc/private_include/libc/file.h @@ -1,4 +1,33 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + #ifndef LIBC_FILE_H #define LIBC_FILE_H +#include <stdio.h> + +struct __file +{ + int fd, eof, error; + char buf[BUFSIZ]; + size_t i; +}; + +extern struct __file *__files[FOPEN_MAX]; + #endif diff --git a/src/libc/src/CMakeLists.txt b/src/libc/src/CMakeLists.txt index 11e7a3c..cf88cdc 100644 --- a/src/libc/src/CMakeLists.txt +++ b/src/libc/src/CMakeLists.txt @@ -15,6 +15,7 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. target_sources(c PRIVATE + _putchar.c errno.c ta_init.c ) @@ -25,6 +26,7 @@ add_subdirectory(stdlib) add_subdirectory(string) if(NOT LIBC_FREESTANDING) + target_sources(c PRIVATE malloc_init.c) add_subdirectory(time) add_subdirectory(unistd) endif() diff --git a/src/libc/src/_putchar.c b/src/libc/src/_putchar.c new file mode 100644 index 0000000..df797c6 --- /dev/null +++ b/src/libc/src/_putchar.c @@ -0,0 +1,24 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stdio.h> + +void _putchar(const char c) +{ + putchar(c); +} diff --git a/src/libc/src/malloc_init.c b/src/libc/src/malloc_init.c new file mode 100644 index 0000000..1ec87e8 --- /dev/null +++ b/src/libc/src/malloc_init.c @@ -0,0 +1,29 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <libc/malloc.h> +#include <tinyalloc.h> +#include <stdint.h> + +void __malloc_init(void) +{ + /* README.md states 16 is a "good default value". */ + if (!ta_init(300, 16, sizeof (intmax_t))) + abort(); +} diff --git a/src/libc/src/ps1/CMakeLists.txt b/src/libc/src/ps1/CMakeLists.txt index 1bab87a..25d64a4 100644 --- a/src/libc/src/ps1/CMakeLists.txt +++ b/src/libc/src/ps1/CMakeLists.txt @@ -15,7 +15,6 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. target_sources(c PRIVATE - putchar.c setjmp.c ) diff --git a/src/libc/src/stdio/CMakeLists.txt b/src/libc/src/stdio/CMakeLists.txt index ca590a1..a4a60d9 100644 --- a/src/libc/src/stdio/CMakeLists.txt +++ b/src/libc/src/stdio/CMakeLists.txt @@ -15,5 +15,11 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. target_sources(c PRIVATE + fopen.c + fputc.c + fwrite.c + putchar.c + putc.c puts.c + streams.c ) diff --git a/src/libc/src/stdio/fopen.c b/src/libc/src/stdio/fopen.c new file mode 100644 index 0000000..4c47f5a --- /dev/null +++ b/src/libc/src/stdio/fopen.c @@ -0,0 +1,95 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <libc/file.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> + +static int find_free(void) +{ + for (size_t i = 0; i < sizeof __files / sizeof *__files; i++) + if (!__files[i]) + return i; + + return -1; +} + +static int convert(const char *mode) +{ + int ret = 0; + + if (!mode) + return -1; + else if (*mode == 'r') + ret |= O_RDONLY; + else if (*mode == 'w') + ret |= O_WRONLY | O_CREAT; + else if (*mode == 'a') + ret |= O_WRONLY | O_CREAT | O_APPEND; + + if (*++mode == '+') + ret |= O_RDWR; + + if (!ret) + return -1; + + return ret; +} + +FILE *fopen(const char *const path, const char *const mode) +{ + FILE *ret = NULL; + int i, flags, fd = -1; + mode_t mask; + + if (!path || (flags = convert(mode)) < 0) + { + errno = EINVAL; + goto failure; + } + else if ((i = find_free()) < 0) + { + errno = EMFILE; + goto failure; + } + + mask = umask(0); + umask(mask); + + if ((fd = open(path, flags, 0666 & ~mask)) < 0) + goto failure; + else if (!(ret = malloc(sizeof *ret))) + goto failure; + + *ret = (const struct __file){.fd = fd}; + __files[i] = ret; + return ret; + +failure: + + if (fd >= 0) + close(fd); + + free(ret); + return NULL; +} diff --git a/src/libc/src/stdio/fputc.c b/src/libc/src/stdio/fputc.c new file mode 100644 index 0000000..10fe4c6 --- /dev/null +++ b/src/libc/src/stdio/fputc.c @@ -0,0 +1,40 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stddef.h> +#include <stdio.h> +#include <libc/file.h> + +int fputc(const int ic, FILE *const f) +{ + const unsigned char c = ic; + + f->buf[f->i++] = c; + + if (c == '\n' || f->i >= sizeof f->buf) + { + const size_t n = fwrite(f->buf, f->i, 1, f); + + f->i = 0; + + if (!n) + return EOF; + } + + return c; +} diff --git a/src/libc/src/stdio/fwrite.c b/src/libc/src/stdio/fwrite.c new file mode 100644 index 0000000..96a4daf --- /dev/null +++ b/src/libc/src/stdio/fwrite.c @@ -0,0 +1,50 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stddef.h> +#include <stdio.h> +#include <libc/file.h> +#include <unistd.h> + +size_t fwrite(const void *const p, const size_t sz, const size_t nmemb, + FILE *const f) +{ + size_t ret = 0; + const char *b = p; + + for (size_t i = 0; i < nmemb; i++, ret++) + { + size_t rem = sz; + + while (rem) + { + const ssize_t n = write(f->fd, b, rem); + + if (n < 0) + { + f->error = 1; + return 0; + } + + b += n; + rem -= n; + } + } + + return ret; +} diff --git a/src/libc/src/stdio/putc.c b/src/libc/src/stdio/putc.c new file mode 100644 index 0000000..b8d015d --- /dev/null +++ b/src/libc/src/stdio/putc.c @@ -0,0 +1,25 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stddef.h> +#include <stdio.h> + +int putc(const int c, FILE *const f) +{ + return fputc(c, f); +} diff --git a/src/libc/src/ps1/putchar.c b/src/libc/src/stdio/putchar.c index 81c98ec..290ad97 100644 --- a/src/libc/src/ps1/putchar.c +++ b/src/libc/src/stdio/putchar.c @@ -20,10 +20,5 @@ int putchar(const int c) { - return EOF; -} - -void _putchar(const char c) -{ - putchar(c); + return putc(c, stdout); } diff --git a/src/libc/src/stdio/streams.c b/src/libc/src/stdio/streams.c new file mode 100644 index 0000000..d88caa1 --- /dev/null +++ b/src/libc/src/stdio/streams.c @@ -0,0 +1,24 @@ +/* + * wnix, a Unix-like operating system for WebAssembly applications. + * Copyright (C) 2025 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <libc/file.h> +#include <unistd.h> + +struct __file *__stdin, *__stdout, *__stderr; +struct __file *__files[FOPEN_MAX]; diff --git a/src/libc/src/stdlib/malloc.c b/src/libc/src/stdlib/malloc.c index 786f314..9025491 100644 --- a/src/libc/src/stdlib/malloc.c +++ b/src/libc/src/stdlib/malloc.c @@ -20,16 +20,12 @@ #include <libc/malloc.h> #include <tinyalloc.h> #include <errno.h> -#include <stdint.h> void *__malloc(const size_t n) { if (!__malloc_ta_init) { - /* README.md states 16 is a "good default value". */ - if (!ta_init(300, 16, sizeof (intmax_t))) - abort(); - + __malloc_init(); __malloc_ta_init = 1; } diff --git a/src/libc/src/unistd/sbrk.c b/src/libc/src/unistd/sbrk.c index b41c192..5d193da 100644 --- a/src/libc/src/unistd/sbrk.c +++ b/src/libc/src/unistd/sbrk.c @@ -25,9 +25,6 @@ static char *base = __bss_end; void *sbrk(const intptr_t increment) { - - - if (base + increment >= __ram_end) return NULL; diff --git a/src/libc/tinyalloc b/src/libc/tinyalloc -Subproject fd8128d9b84e362abdbd05fafe252421edee8ab +Subproject e32da5559962c6131e1f933a245526d699d45cf |
