diff --git a/config.default.mk b/config.default.mk index 4ce1434..5e33bcb 100644 --- a/config.default.mk +++ b/config.default.mk @@ -10,6 +10,6 @@ LD = $(CROSS_PATH)/$(ARCH)-linux-ld # Compilation flags CFLAGS = -std=c17 -Wall -ffreestanding -fpic -nostdlib -fstack-protector-all -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -mno-sse -mno-mmx -mno-80387 -CPPFLAGS = -Ignuefi/inc -Iinclude +CPPFLAGS = -Ignuefi/inc -Iinclude -Ilibc/include LDFLAGS = -shared -Bsymbolic -Lgnuefi -Tgnuefi/elf_$(ARCH)_efi.lds -nostdlib LIBS = -lgnuefi -lefi diff --git a/libc/include/string.h b/libc/include/string.h index 727e9ea..ade8838 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -1,164 +1,44 @@ -/* - * Copyright (c) 2011, 2012, 2013, 2014, 2017, 2024 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string.h - * String operations. - */ +#ifndef VISOR_LIBC_STRING_H +#define VISOR_LIBC_STRING_H -#ifndef _INCLUDE_STRING_H -#define _INCLUDE_STRING_H - -#include - -#if __USE_SORTIX || __USE_POSIX -#include -#endif - -#ifndef NULL -#define __need_NULL #include -#endif -#ifndef __size_t_defined -#define __size_t_defined -#define __need_size_t -#include -#endif +int ffs(int); +int ffsl(long); +int ffsll(long long); -#if __USE_SORTIX || 2008 <= __USE_POSIX -#ifndef __locale_t_defined -#define __locale_t_defined -/* TODO: figure out what this does and typedef it properly. This is just a - temporary assignment. */ -typedef int __locale_t; -typedef __locale_t locale_t; -#endif -#endif +void *memccpy(void *restrict, const void *restrict, int, size_t); +void *memchr (const void *, int, size_t); +int memcmp (const void *, const void *, size_t); +void *memcpy (void *restrict, const void *restrict, size_t); +void *memmove(void *, const void *, size_t); +void *memrchr(const void *, int, size_t); +void *memset (void *, int, size_t); -#ifdef __cplusplus -extern "C" { -#endif +char *stpcpy (char *restrict, const char *restrict); +char *stpncpy(char *restrict, const char *restrict, size_t); -void* memchr(const void*, int, size_t); -int memcmp(const void*, const void*, size_t); -void* memcpy(void* __restrict, const void* __restrict, size_t); -void* memmove(void*, const void*, size_t); -void* memset(void*, int, size_t); -char* strcat(char* __restrict, const char* __restrict); -char* strchr(const char*, int); -int strcmp(const char*, const char*); -int strcoll(const char*, const char*); -char* strcpy(char* __restrict, const char* __restrict); -size_t strcspn(const char*, const char*); -char* strerror(int errnum); -size_t strlen(const char*); -char* strncat(char* __restrict, const char* __restrict, size_t); -int strncmp(const char*, const char*, size_t); -char* strncpy(char* __restrict, const char* __restrict, size_t); -char* strpbrk(const char*, const char*); -char* strrchr(const char*, int); -size_t strspn(const char*, const char*); -char* strstr(const char*, const char*); -char* strtok(char* __restrict, const char* __restrict); -size_t strxfrm(char* __restrict, const char* __restrict, size_t); - -/* Functions from early POSIX. */ -#if __USE_SORTIX || __USE_POSIX -int strcasecmp(const char* a, const char* b); -int strncasecmp(const char* a, const char* b, size_t n); -#endif - -/* Functions from early XOPEN. */ -#if __USE_SORTIX || __USE_XOPEN -void* memccpy(void* __restrict, const void* __restrict, int, size_t); -int ffs(int); -#endif - -/* Functions from XOPEN 420 gone into POSIX 2008. */ -#if __USE_SORTIX || 420 <= __USE_XOPEN || 200809L <= __USE_POSIX -char* strdup(const char*); -#endif - -/* Functions from POSIX 2001. */ -#if __USE_SORTIX || 200112L <= __USE_POSIX -char* strerror_l(int, locale_t); -int strerror_r(int, char*, size_t); -char* strtok_r(char* __restrict, const char* __restrict, char** __restrict); -#endif - -/* Functions from POSIX 2008. */ -#if __USE_SORTIX || 200809L <= __USE_POSIX -char* stpcpy(char* __restrict, const char* __restrict); -char* stpncpy(char* __restrict, const char* __restrict, size_t); -int strcoll_l(const char*, const char*, locale_t); -char* strndup(const char*, size_t); -size_t strnlen(const char*, size_t); -char* strsignal(int signum); -size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t); -#endif - -/* Functions from POSIX 2024. */ -#if __USE_SORTIX || 202405L <= __USE_POSIX -size_t strlcat(char* __restrict, const char* __restrict, size_t); -size_t strlcpy(char* __restrict, const char* __restrict, size_t); -#endif - -#if __USE_SORTIX || 800 <= __USE_XOPEN -int ffsl(long int); -int ffsll(long long int); -#endif - -/* Functions copied from elsewhere. */ -#if __USE_SORTIX -void explicit_bzero(void*, size_t); - -void* memrchr(const void*, int, size_t); -/* TODO: strcasecmp_l */ -char* strchrnul(const char* str, int c); -char* stresep(char**, const char*, int); -/* TODO: strncasecmp_l */ -char* strsep(char**, const char*); -int strverscmp(const char*, const char*); -int timingsafe_memcmp(const void*, const void*, size_t); -#endif - -#if __USE_SORTIX -/* Duplicate S, returning an identical alloca'd string. */ -#define strdupa(s) \ - (__extension__ \ - ({ \ - const char* __old = (s); \ - size_t __len = strlen(__old) + 1; \ - char* __new = (char*) __builtin_alloca(__len); \ - (char*) memcpy(__new, __old, __len); \ - })) - -/* Return an alloca'd copy of at most N bytes of string. */ -#define strndupa(s, n) \ - (__extension__ \ - ({ \ - __const char* __old = (s); \ - size_t __len = strnlen(__old, (n)); \ - char* __new = (char*) __builtin_alloca(__len + 1); \ - __new[__len] = '\0'; \ - (char*) memcpy(__new, __old, __len); \ - })) -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif +char *strcat (char *restrict, const char *restrict); +char *strchr (const char *, int); +int strcmp (const char *, const char *); +char *strchrnul(const char *, int); +int strcoll(const char *, const char *); +char *strcpy (char *restrict, const char *restrict); +size_t strcspn(const char *, const char *); +char *stresep(char **, const char *, int); +size_t strlcat(char *restrict, const char *restrict, size_t); +size_t strlcpy(char *restrict, const char *restrict, size_t); +size_t strlen (const char *); +char *strncat(char *restrict, const char *restrict, size_t); +int strncmp(const char *, const char *, size_t); +char *strncpy(char *restrict, const char *restrict, size_t); +size_t strnlen(const char *, size_t); +char *strpbrk(const char *, const char *); +char *strrchr(const char *, int); +char *strsep (char **, const char *); +size_t strspn (const char *, const char *); +char *strstr (const char *, const char *); +char *strtok_r(char *restrict, const char *restrict, char **restrict); +size_t strxfrm(char *restrict, const char *restrict, size_t); #endif diff --git a/libc/string/explicit_bzero.c b/libc/string/explicit_bzero.c deleted file mode 100644 index e3998a0..0000000 --- a/libc/string/explicit_bzero.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/explicit_bzero.c - * Initializes a region of memory to a byte value in a manner that is not - * optimized away by the compiler. - */ - -#include - -// TODO: Employ special compiler support to ensure this is not optimized away. -void explicit_bzero(void* dest_ptr, size_t size) -{ - volatile unsigned char* dest = (volatile unsigned char*) dest_ptr; - for ( size_t i = 0; i < size; i++ ) - dest[i] = 0; -} diff --git a/libc/string/memcpy.c b/libc/string/memcpy.c deleted file mode 100644 index bb5e836..0000000 --- a/libc/string/memcpy.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014, 2015, 2016 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/memcpy.c - * Copy memory between non-overlapping regions. - */ - -#include -#include -#include -#include - -#if defined(__is_sortix_libk) -#include -#endif - -inline static -void* memcpy_slow(void* restrict dst_ptr, - const void* restrict src_ptr, - size_t size) -{ - unsigned char* restrict dst = (unsigned char* restrict) dst_ptr; - const unsigned char* restrict src = (const unsigned char* restrict) src_ptr; - for ( size_t i = 0; i < size; i++ ) - dst[i] = src[i]; - return dst_ptr; -} - -void* memcpy(void* restrict dst_ptr, - const void* restrict src_ptr, - size_t size) -{ - if ( dst_ptr == src_ptr || !size ) - return dst_ptr; - - void* dst_end = (char*) dst_ptr + size; - const void* src_end = (const char*) src_ptr + size; - if ( (dst_ptr < src_ptr && src_ptr < dst_end) || - (src_ptr < dst_ptr && dst_ptr < src_end) ) - { -#if defined(__is_sortix_libk) - libk_overlapping_memcpy(); -#else - struct scram_undefined_behavior info; - info.filename = __FILE__; - info.line = __LINE__; - info.column = 0; - info.violation = "overlapping memcpy"; - scram(SCRAM_UNDEFINED_BEHAVIOR, &info); -#endif - } - -#if 8 < __SIZEOF_LONG__ -#warning "you should add support for your unexpectedly large unsigned long." - return memcpy_slow(dst_ptr, src_ptr, size); -#else - unsigned long unalign_mask = sizeof(unsigned long) - 1; - unsigned long src_unalign = (unsigned long) src_ptr & unalign_mask; - unsigned long dst_unalign = (unsigned long) dst_ptr & unalign_mask; - if ( src_unalign != dst_unalign ) - return memcpy_slow(dst_ptr, src_ptr, size); - - union - { - unsigned long srcval; - const unsigned char* restrict src8; - const uint16_t* restrict src16; - const uint32_t* restrict src32; - const uint64_t* restrict src64; - const unsigned long* restrict srcul; - } su; - su.srcval = (unsigned long) src_ptr; - - union - { - unsigned long dstval; - unsigned char* restrict dst8; - uint16_t* restrict dst16; - uint32_t* restrict dst32; - uint64_t* restrict dst64; - unsigned long* restrict dstul; - } du; - du.dstval = (unsigned long) dst_ptr; - - if ( dst_unalign ) - { - if ( 1 <= size && !(du.dstval & (1-1)) && (du.dstval & (2-1)) ) - *du.dst8++ = *su.src8++, - size -= 1; - - if ( 2 <= size && !(du.dstval & (2-1)) && (du.dstval & (4-1)) ) - *du.dst16++ = *su.src16++, - size -= 2; - - #if 8 <= __SIZEOF_LONG__ - if ( 4 <= size && !(du.dstval & (4-1)) && (du.dstval & (8-1)) ) - *du.dst32++ = *su.src32++, - size -= 4; - #endif - } - - size_t num_copies = size / sizeof(unsigned long); - for ( size_t i = 0; i < num_copies; i++ ) - *du.dstul++ = *su.srcul++; - - size -= num_copies * sizeof(unsigned long); - - if ( size ) - { - #if 8 <= __SIZEOF_LONG__ - if ( 4 <= size ) - *du.dst32++ = *su.src32++, - size -= 4; - #endif - - if ( 2 <= size ) - *du.dst16++ = *su.src16++, - size -= 2; - - if ( 1 <= size ) - *du.dst8++ = *su.src8++, - size -= 1; - } - - return dst_ptr; -#endif -} diff --git a/libc/string/memset.c b/libc/string/memset.c deleted file mode 100644 index e247ac6..0000000 --- a/libc/string/memset.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/memset.c - * Initializes a region of memory to a byte value. - */ - -#include -#include - -#include <__/wordsize.h> - -void* memset(void* dest_ptr, int value, size_t length) -{ - unsigned char* dest = (unsigned char*) dest_ptr; -#if __WORDSIZE == 32 || __WORDSIZE == 64 - if ( ((uintptr_t) dest_ptr & (sizeof(unsigned long) - 1)) == 0 ) - { - unsigned long* ulong_dest = (unsigned long*) dest; - size_t ulong_length = length / sizeof(unsigned long); -#if __WORDSIZE == 32 - unsigned long ulong_value = - (unsigned long) ((unsigned char) value) << 0 | - (unsigned long) ((unsigned char) value) << 8 | - (unsigned long) ((unsigned char) value) << 16 | - (unsigned long) ((unsigned char) value) << 24; -#elif __WORDSIZE == 64 - unsigned long ulong_value = - (unsigned long) ((unsigned char) value) << 0 | - (unsigned long) ((unsigned char) value) << 8 | - (unsigned long) ((unsigned char) value) << 16 | - (unsigned long) ((unsigned char) value) << 24 | - (unsigned long) ((unsigned char) value) << 32 | - (unsigned long) ((unsigned char) value) << 40 | - (unsigned long) ((unsigned char) value) << 48 | - (unsigned long) ((unsigned char) value) << 56; -#endif - for ( size_t i = 0; i < ulong_length; i++ ) - ulong_dest[i] = ulong_value; - dest += ulong_length * sizeof(unsigned long); - length -= ulong_length * sizeof(unsigned long); - } -#endif - for ( size_t i = 0; i < length; i++ ) - dest[i] = (unsigned char) value; - return dest_ptr; -} diff --git a/libc/string/strcasecmp.c b/libc/string/strcasecmp.c deleted file mode 100644 index 8c0e4a5..0000000 --- a/libc/string/strcasecmp.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strcasecmp.c - * Compares two strings ignoring case. - */ - -#include -#include -#include - -int strcasecmp(const char* a, const char* b) -{ - for ( size_t i = 0; true; i++ ) - { - unsigned char ac = (unsigned char) tolower((unsigned char) a[i]); - unsigned char bc = (unsigned char) tolower((unsigned char) b[i]); - if ( ac == '\0' && bc == '\0' ) - return 0; - if ( ac < bc ) - return -1; - if ( ac > bc ) - return 1; - } -} diff --git a/libc/string/strcoll_l.c b/libc/string/strcoll_l.c deleted file mode 100644 index 15eb017..0000000 --- a/libc/string/strcoll_l.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strcoll_l.c - * Compare two strings using the given locale. - */ - -#include - -int strcoll_l(const char* s1, const char* s2, locale_t locale) -{ - (void) locale; - return strcoll(s1, s2); -} diff --git a/libc/string/strdup.c b/libc/string/strdup.c deleted file mode 100644 index 66d073c..0000000 --- a/libc/string/strdup.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strdup.c - * Creates a copy of a string. - */ - -#include -#include - -char* strdup(const char* input) -{ - size_t input_length = strlen(input); - char* result = (char*) malloc(input_length + 1); - if ( !result ) - return NULL; - memcpy(result, input, input_length + 1); - return result; -} diff --git a/libc/string/strerror.c b/libc/string/strerror.c deleted file mode 100644 index 1c4949e..0000000 --- a/libc/string/strerror.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2011-2016, 2020-2022, 2024 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strerror.c - * Convert error code to a string. - */ - -#include -#include - -char* strerror(int errnum) -{ - switch ( errnum ) - { - case ENOTBLK: return "Block device required"; - case ENODEV: return "No such device"; - case EBADF: return "Bad file descriptor"; - case EOVERFLOW: return "Value too large to be stored in data type"; - case ENOENT: return "No such file or directory"; - case ENOSPC: return "No space left on device"; - case EEXIST: return "File exists"; - case EROFS: return "Read-only file system"; - case EINVAL: return "Invalid argument"; - case ENOTDIR: return "Not a directory"; - case ENOMEM: return "Not enough memory"; - case ERANGE: return "Result too large"; - case EISDIR: return "Is a directory"; - case EPERM: return "Operation not permitted"; - case EIO: return "Input/output error"; - case ENOEXEC: return "Exec format error"; - case EACCES: return "Permission denied"; - case ESRCH: return "No such process"; - case ENOTTY: return "Not a tty"; - case ECHILD: return "No child processes"; - case ENOSYS: return "Function not implemented"; - case ENOTSUP: return "Operation not supported"; - case EBLOCKING: return "Operation is blocking"; - case EINTR: return "Interrupted function call"; - case ENOTEMPTY: return "Directory not empty"; - case EBUSY: return "Device or resource busy"; - case EPIPE: return "Broken pipe"; - case EILSEQ: return "Invalid byte sequence"; - case ELAKE: return "Sit by a lake"; - case EMFILE: return "Too many open files"; - case EAGAIN: return "Resource temporarily unavailable"; - case EEOF: return "End of file"; - case EBOUND: return "Out of bounds"; - case EINIT: return "Not initialized"; - case ENODRV: return "No such driver"; - case E2BIG: return "Argument list too long"; - case EFBIG: return "File too large"; - case EXDEV: return "Improper link"; - case ESPIPE: return "Cannot seek on stream"; - case ENAMETOOLONG: return "Filename too long"; - case ELOOP: return "Too many levels of symbolic links"; - case EMLINK: return "Too many links"; - case ENXIO: return "No such device or address"; - case EPROTONOSUPPORT: return "Protocol not supported"; - case EAFNOSUPPORT: return "Address family not supported"; - case ENOTSOCK: return "Not a socket"; - case EADDRINUSE: return "Address already in use"; - case ETIMEDOUT: return "Connection timed out"; - case ECONNREFUSED: return "Connection refused"; - case EDOM: return "Mathematics argument out of domain of function"; - case EINPROGRESS: return "Operation in progress"; - case EALREADY: return "Connection already in progress"; - case ESHUTDOWN: return "Cannot send after transport endpoint shutdown"; - case ECONNABORTED: return "Connection aborted"; - case ECONNRESET: return "Connection reset"; - case EADDRNOTAVAIL: return "Address not available"; - case EISCONN: return "Socket is connected"; - case EFAULT: return "Bad address"; - case EDESTADDRREQ: return "Destination address required"; - case EHOSTUNREACH: return "Host is unreachable"; - case EMSGSIZE: return "Message too long"; - case ENETDOWN: return "Network is down"; - case ENETRESET: return "Connection aborted by network"; - case ENETUNREACH: return "Network is unreachable"; - case ENOBUFS: return "No buffer space available"; - case ENOMSG: return "No message of the desired type"; - case ENOPROTOOPT: return "Protocol not available"; - case ENOTCONN: return "Socket is not connected"; - case EDEADLK: return "Resource deadlock avoided"; - case ENFILE: return "Too many open files in system"; - case EPROTOTYPE: return "Wrong protocol type for socket"; - case ENOLCK: return "No locks available"; - case ESIGPENDING: return "Signal is already pending"; - case ESTALE: return "Stale file handle"; - case EBADMSG: return "Bad message"; - case ECANCELED: return "Operation canceled"; - case EDQUOT: return "Disk quota exceeded"; - case EIDRM: return "Identifier removed"; - case EMULTIHOP: return "Multihop attempted"; - case ENOLINK: return "Link has been severed"; - case ENOTRECOVERABLE: return "State not recoverable"; - case EOWNERDEAD: return "Previous owner died"; - case EPROTO: return "Protocol error"; - case ETXTBSY: return "Text file busy"; - case ENOMOUNT: return "No such mountpoint"; - case ENOMEDIUM: return "No medium found"; - case EHOSTDOWN: return "Host is down"; - case ESOCKTNOSUPPORT: return "Socket type is not supported"; - default: return "Unknown error condition"; - } -} - -// TODO: After releasing Sortix 1.1, or after fixing ffmpeg, remove this symbol -// retained for compatibility. ffmpeg has a native sysroot issue where it -// accidentally taints it with the local system's headers instead of the -// sysroot headers, which accidentally pulls in an old removed symbol when -// bootstrapping on an old system. -weak_alias(strerror, sortix_strerror); diff --git a/libc/string/strerror_l.c b/libc/string/strerror_l.c deleted file mode 100644 index 5f238fd..0000000 --- a/libc/string/strerror_l.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013, 2024 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strerror_l.c - * Convert error code to a string. - */ - -#include - -char* strerror_l(int errnum, locale_t locale) -{ - (void) locale; - return (char*) strerror(errnum); -} diff --git a/libc/string/strerror_r.c b/libc/string/strerror_r.c deleted file mode 100644 index a7cba7f..0000000 --- a/libc/string/strerror_r.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2013, 2014, 2024 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strerror_r.c - * Convert error code to a string. - */ - -#include -#include - -int strerror_r(int errnum, char* dest, size_t dest_len) -{ - const char* msg = strerror(errnum); - if ( !msg ) - return -1; - if ( dest_len < strlen(msg) + 1 ) - return errno = ERANGE; - strcpy(dest, msg); - return 0; -} diff --git a/libc/string/strncasecmp.c b/libc/string/strncasecmp.c deleted file mode 100644 index 5865453..0000000 --- a/libc/string/strncasecmp.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strncasecmp.c - * Compares a prefix of two strings ignoring case. - */ - -#include -#include - -int strncasecmp(const char* a, const char* b, size_t max_count) -{ - for ( size_t i = 0; i < max_count; i++ ) - { - unsigned char ac = (unsigned char) tolower((unsigned char) a[i]); - unsigned char bc = (unsigned char) tolower((unsigned char) b[i]); - if ( ac == '\0' && bc == '\0' ) - return 0; - if ( ac < bc ) - return -1; - if ( ac > bc ) - return 1; - } - return 0; -} diff --git a/libc/string/strndup.c b/libc/string/strndup.c deleted file mode 100644 index c9ade08..0000000 --- a/libc/string/strndup.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strndup.c - * Creates a copy of a string. - */ - -#include -#include - -char* strndup(const char* input, size_t n) -{ - size_t input_size = strnlen(input, n); - char* result = (char*) malloc(input_size + 1); - if ( !result ) - return NULL; - memcpy(result, input, input_size); - result[input_size] = 0; - return result; -} diff --git a/libc/string/strsignal.c b/libc/string/strsignal.c deleted file mode 100644 index d5f884c..0000000 --- a/libc/string/strsignal.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2012, 2014, 2024 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strsignal.c - * Convert signal number to a string. - */ - -#include -#include - -char* strsignal(int signum) -{ - switch ( signum ) - { - case SIGHUP: return "Hangup"; - case SIGINT: return "Interrupt"; - case SIGQUIT: return "Quit"; - case SIGILL: return "Invalid instruction"; - case SIGTRAP: return "Trace/breakpoint trap"; - case SIGABRT: return "Aborted"; - case SIGBUS: return "Bus Error"; - case SIGFPE: return "Floating point exception"; - case SIGKILL: return "Killed"; - case SIGUSR1: return "User defined signal 1"; - case SIGSEGV: return "Segmentation fault"; - case SIGUSR2: return "User defined signal 2"; - case SIGPIPE: return "Broken pipe"; - case SIGALRM: return "Alarm clock"; - case SIGTERM: return "Terminated"; - case SIGSYS: return "Bad system call"; - case SIGCHLD: return "Child exited"; - case SIGCONT: return "Continued"; - case SIGSTOP: return "Stopped (signal)"; - case SIGTSTP: return "Stopped"; - case SIGTTIN: return "Stopped (tty input)"; - case SIGTTOU: return "Stopped (tty output)"; - case SIGURG: return "Urgent I/O condition"; - case SIGXCPU: return "CPU time limit exceeded"; - case SIGXFSZ: return "File size limit exceeded"; - case SIGVTALRM: return "Virtual timer expired"; - case SIGPWR: return "Power Fail/Restart"; - case SIGWINCH: return "Window changed"; - default: break; - } - - if ( SIGRTMIN <= signum && signum <= SIGRTMAX ) - return "Real-time signal"; - - return "Unknown signal value"; -} diff --git a/libc/string/strtok.c b/libc/string/strtok.c deleted file mode 100644 index 68b1870..0000000 --- a/libc/string/strtok.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strtok.c - * Extract tokens from strings. - */ - -#include - -char* strtok(char* str, const char* delim) -{ - static char* lasttokensaveptr = NULL; - return strtok_r(str, delim, &lasttokensaveptr); -} diff --git a/libc/string/strverscmp.c b/libc/string/strverscmp.c deleted file mode 100644 index ef7403f..0000000 --- a/libc/string/strverscmp.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strverscmp.c - * Compares two version strings. - */ - -#include -#include - -static bool is_number(char c) -{ - return '0' <= c && c <= '9'; -} - -static int to_number(char c) -{ - return c - '0'; -} - -int strverscmp(const char* a, const char* b) -{ - for ( size_t i = 0; true; i++ ) - { - // Be a regular strcmp if the strings are equal. - if ( a[i] == '\0' && b[i] == '\0' ) - return 0; - if ( a[i] == b[i] ) - continue; - - // Be a regular strcmp if no digits are involed when they differ. - // Note: This implementation uses version number comparison if *either* - // of the first differing characters are digits, unlike glibc - // which is documented to require *both*. This behavior matches - // GNU sort -V and musl. It's also useful as "1.2.txt" compares - // before "1.2.3.txt". - bool version_string = is_number(a[i]) || is_number(b[i]); - if ( !version_string && a[i] < b[i] ) - return -1; - if ( !version_string && a[i] > b[i] ) - return 1; - - // Because the number of leading zeroes matter, we have to find the - // entire numeric block we are currently within. We know the strings are - // equal until i, so we can simply find the number of shared digits by - // looking in the first string. - size_t digits_start = i; - while ( digits_start && is_number(a[digits_start-1]) ) - digits_start--; - size_t shared_digits = i - digits_start; - - // Find the number of shared leading zeroes. - size_t shared_zeroes = 0; - while ( shared_zeroes < shared_digits && - to_number(a[digits_start + shared_zeroes]) == 0 ) - shared_zeroes++; - - // Try to expand the leading zeroes amount into a. - size_t a_zeroes = shared_zeroes; - while ( is_number(a[digits_start + a_zeroes]) == 0 ) - a_zeroes++; - - // Try to expand the leading zeroes amount into b. - size_t b_zeroes = shared_zeroes; - while ( is_number(b[digits_start + b_zeroes]) == 0 ) - b_zeroes++; - - // We treat strings with leading zeroes as if they have a decimal point - // in front of them, so strings with more zeroes sort lower. - if ( a_zeroes > b_zeroes ) - return -1; - if ( b_zeroes > a_zeroes ) - return 1; - - // Find the number of consecutive digits in a where the strings differ. - size_t a_digits = a_zeroes; - while ( is_number(a[digits_start + a_digits]) ) - a_digits++; - - // Find the number of consecutive digits in b where the strings differ. - size_t b_digits = b_zeroes; - while ( is_number(b[digits_start + b_digits]) ) - b_digits++; - - // We know the strings have the same amount of leading zeroes, so we - // so if a a block is longer than the other, then the value must be - // longer as well. - if ( a_digits < b_digits ) - return -1; - if ( b_digits < a_digits ) - return 1; - - // Finally run through the strings from where they differ and sort them - // numerically. We know this terminates because the strings differ. The - // strings have the same amount of digits, so comparing them is easy. - for ( size_t n = shared_zeroes; true; n++ ) - { - if ( a[digits_start + n] < b[digits_start + n] ) - return -1; - if ( b[digits_start + n] < a[digits_start + n] ) - return 1; - } - } -} diff --git a/libc/string/strxfrm_l.c b/libc/string/strxfrm_l.c deleted file mode 100644 index 67829f0..0000000 --- a/libc/string/strxfrm_l.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * string/strxfrm_l.c - * Transform a string such that the result of strcmp is the same as strcoll_l. - */ - -#include - -size_t strxfrm_l(char* dest, const char* src, size_t n, locale_t locale) -{ - (void) locale; - return strxfrm(dest, src, n); -} diff --git a/libc/string/timingsafe_memcmp.c b/libc/string/timingsafe_memcmp.c deleted file mode 100644 index 7f3262e..0000000 --- a/libc/string/timingsafe_memcmp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* $OpenBSD: timingsafe_memcmp.c,v 1.1 2014/06/13 02:12:17 matthew Exp $ */ -/* - * Copyright (c) 2014 Google Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -// TODO: I don't fully trust that this code is _always_ timing safe in the -// presence of very smart compilers that can prove that this computes the -// same value as memcmp and could be short-circuited. We should invent and -// rely on compiler extensions that inform the compiler that sensitive -// information is involved, which forbids the compiler code generation -// from branching on the information (and such). -// TODO: We should add testcases that verify this is actually timing safe. - -int timingsafe_memcmp(const void* a_ptr, const void* b_ptr, size_t size) -{ - const unsigned char* a = (const unsigned char*) a_ptr; - const unsigned char* b = (const unsigned char*) b_ptr; - int result = 0; - int done = 0; - for ( size_t i = 0; i < size; i++ ) - { - /* lt is -1 if a[i] < b[i]; else 0. */ - int lt = (a[i] - b[i]) >> CHAR_BIT; - - /* gt is -1 if a[i] > b[i]; else 0. */ - int gt = (b[i] - a[i]) >> CHAR_BIT; - - /* cmp is 1 if a[i] > b[i]; -1 if a[i] < b[i]; else 0. */ - int cmp = lt - gt; - - /* set result = cmp if !done. */ - result |= cmp & ~done; - - /* set done if a[i] != b[i]. */ - done |= lt | gt; - } - return result; -}