Squash commits for public release

This commit is contained in:
2025-02-12 09:54:05 -05:00
commit 7118adc514
1108 changed files with 80873 additions and 0 deletions

115
libs/libc/stdlib/env.c Normal file
View File

@@ -0,0 +1,115 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
static void free_var(const char* string)
{
// TODO: Implement me!
}
char* getenv(const char* name)
{
size_t len = strlen(name);
for (int i = 0; environ[i]; i++) {
const char* envv = environ[i];
char* eqpos = strchr(envv, '=');
if (!eqpos) {
continue;
}
size_t curlen = (size_t)(eqpos - envv);
if (curlen == len && strncmp(name, envv, len) == 0) {
return (char*)&envv[len + 1];
}
}
return NULL;
}
int setenv(const char* name, const char* value, int overwrite)
{
if (!overwrite && getenv(name)) {
return 0;
}
int name_len = strlen(name);
int value_len = strlen(value);
int len = name_len + 1 + value_len;
char* string = (char*)malloc(len + 1);
strncpy(string, name, name_len);
string[name_len] = '=';
strncpy(&string[name_len + 1], value, value_len);
string[len] = '\0';
return putenv(string);
}
int putenv(char* string)
{
char* pos = strchr(string, '=');
if (!pos) {
return unsetenv(string);
}
size_t len = (size_t)(pos - string);
int env_i = 0;
for (; environ[env_i]; env_i++) {
const char* envv = environ[env_i];
char* eqpos = strchr(envv, '=');
if (!eqpos) {
continue;
}
size_t curlen = (size_t)(eqpos - envv);
if (len != curlen) {
continue;
}
if (strncmp(string, envv, len) == 0) {
free_var(envv);
environ[env_i] = string;
return 0;
}
}
char** new_environ = (char**)malloc(sizeof(char*) * (env_i + 2));
for (int i = 0; i < env_i; i++) {
new_environ[i] = environ[i];
}
new_environ[env_i] = string;
new_environ[env_i + 1] = NULL;
extern int __environ_malloced;
if (__environ_malloced) {
free(environ);
}
environ = new_environ;
__environ_malloced = 1;
return 0;
}
int unsetenv(const char* name)
{
size_t len = strlen(name);
int env_i = 0;
int remove_pos = 0;
const char* remove_env = NULL;
for (; environ[env_i]; env_i++) {
const char* envv = environ[env_i];
char* eqpos = strchr(envv, '=');
if (!eqpos) {
continue;
}
size_t curlen = (size_t)(eqpos - envv);
if (len != curlen) {
continue;
}
if (strncmp(name, envv, len) == 0) {
remove_pos = env_i;
remove_env = envv;
}
}
size_t move_len = ((env_i - 1) - remove_pos) * sizeof(char*);
memmove(&environ[remove_pos], &environ[remove_pos + 1], move_len);
free_var(remove_env);
return 0;
}

15
libs/libc/stdlib/exit.c Normal file
View File

@@ -0,0 +1,15 @@
#include <signal.h>
#include <stdlib.h>
#include <sysdep.h>
void exit(int status)
{
DO_SYSCALL_1(SYS_EXIT, status);
__builtin_unreachable();
}
void abort()
{
raise(SIGABRT);
exit(127);
}

50
libs/libc/stdlib/pts.c Normal file
View File

@@ -0,0 +1,50 @@
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define _PATH_PTS "/dev/pts"
#define MASTER_PTY(dev) (major(dev) == 128)
#define SLAVE_PTY(dev) (major(dev) == 136)
int posix_openpt(int flags)
{
return open("/dev/ptmx", flags);
}
int ptsname_r(int fd, char* buf, size_t buflen)
{
int len = strlen(_PATH_PTS);
if (buflen < len + 2) {
set_errno(ERANGE);
return -ERANGE;
}
stat_t stat;
if (fstat(fd, &stat) < 0) {
return errno;
}
if (!MASTER_PTY(stat.st_dev)) {
set_errno(ENOTTY);
return -ENOTTY;
}
int ptyno = minor(stat.st_dev);
char* p = strcpy(buf, _PATH_PTS);
p[len + 0] = '0' + ptyno;
p[len + 1] = '\0';
return 0;
}
static char ptsbuf[32];
char* ptsname(int fd)
{
if (ptsname_r(fd, ptsbuf, sizeof(ptsbuf)) < 0) {
return NULL;
}
return ptsbuf;
}

144
libs/libc/stdlib/tools.c Normal file
View File

@@ -0,0 +1,144 @@
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
int atoi(const char* s)
{
// FIXME: Add overflow checks
int res = 0;
int len = strlen(s);
int mul = 1;
for (int i = 0; i < len; i++) {
mul *= 10;
}
for (int i = 0; i < len; i++) {
mul /= 10;
res += (s[i] - '0') * mul;
}
return res;
}
long strtol(const char* nptr, char** endptr, int base)
{
const char* p = nptr;
const char* endp = nptr;
bool negative = false;
bool overflow = false;
unsigned long n = 0;
if (base < 0 || base == 1 || base > 36) {
set_errno(EINVAL);
return 0;
}
while (isspace(*p)) {
p++;
}
if (*p == '+') {
p++;
} else if (*p == '-') {
negative = 1;
p++;
}
if (*p == '0') {
p++;
endp = p;
if (base == 16 && (*p == 'X' || *p == 'x')) {
p++;
} else if (base == 0) {
if (*p == 'X' || *p == 'x') {
base = 16, p++;
} else {
base = 8;
}
}
} else if (base == 0) {
base = 10;
}
unsigned long cutoff = (negative) ? -(LONG_MIN / base) : LONG_MAX / base;
int cutlim = (negative) ? -(LONG_MIN % base) : LONG_MAX % base;
for (;;) {
int digit;
if (*p >= 'a') {
digit = (*p - 'a') + 10;
} else if (*p >= 'A') {
digit = *p - 'A' + 10;
} else if (*p <= '9') {
digit = *p - '0';
} else {
break;
}
if (digit < 0 || digit >= base) {
break;
}
p++;
endp = p;
if (overflow) {
if (endptr) {
continue;
}
break;
}
if (n > cutoff || (n == cutoff && digit > cutlim)) {
overflow = 1;
continue;
}
n = n * base + digit;
}
if (endptr) {
*endptr = (char*)endp;
}
if (overflow) {
set_errno(ERANGE);
return ((negative) ? LONG_MIN : LONG_MAX);
}
return (long)((negative) ? -n : n);
}
#define SWAPARR(a, b, size) \
do { \
size_t __size = (size); \
char *__a = (a), *__b = (b); \
do { \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
void __qsortimpl(void* vbase, size_t n, size_t size, int (*compar)(const void*, const void*), int l, int r)
{
char* base = (char*)vbase;
if (l >= r) {
return;
}
int lm = l - 1;
for (int rm = l; rm < r; rm++) {
if (compar(&base[rm * size], &base[r * size]) < 0) {
lm++;
SWAPARR(&base[lm * size], &base[rm * size], size);
}
}
SWAPARR(&base[(lm + 1) * size], &base[r * size], size);
__qsortimpl(vbase, n, size, compar, l, lm);
__qsortimpl(vbase, n, size, compar, lm + 2, r);
}
void qsort(void* vbase, size_t n, size_t size, int (*compar)(const void*, const void*))
{
__qsortimpl(vbase, n, size, compar, 0, n - 1);
}