Add libc implementation stubs
Real string core and process teardown; thin read/write/close/getpid/_exit syscall wrappers; the rest follows the stub convention (documented error return, errno = ENOSYS, TODO). syscall.c is the only kernel ABI surface; crt0.S is the static entry point, kept out of libc.a. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
This commit is contained in:
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* string.c — real, minimal implementations of the memory/string core.
|
||||
*
|
||||
* Byte-at-a-time on purpose: for the sizes Null Linux deals with, and for
|
||||
* the goal of keeping the code obviously correct, word-at-a-time tricks
|
||||
* are not worth the branch soup. If profiling ever says otherwise, the
|
||||
* benchmark suite will say so (see benchmarks/).
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *p = s;
|
||||
while (*p)
|
||||
p++;
|
||||
return (size_t)(p - s);
|
||||
}
|
||||
|
||||
int strcmp(const char *a, const char *b)
|
||||
{
|
||||
while (*a && *a == *b) {
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return (unsigned char)*a - (unsigned char)*b;
|
||||
}
|
||||
|
||||
int strncmp(const char *a, const char *b, size_t n)
|
||||
{
|
||||
for (; n && *a && *a == *b; n--, a++, b++)
|
||||
;
|
||||
if (n == 0)
|
||||
return 0;
|
||||
return (unsigned char)*a - (unsigned char)*b;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src)
|
||||
{
|
||||
char *d = dst;
|
||||
while ((*d++ = *src++))
|
||||
;
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *strncpy(char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *d = dst;
|
||||
while (n && *src) {
|
||||
*d++ = *src++;
|
||||
n--;
|
||||
}
|
||||
while (n--)
|
||||
*d++ = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memcpy(void *restrict dst, const void *restrict src, size_t n)
|
||||
{
|
||||
unsigned char *d = dst;
|
||||
const unsigned char *s = src;
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dst;
|
||||
const unsigned char *s = src;
|
||||
|
||||
if ((size_t)(d - s) >= n) {
|
||||
/* No overlap (or exact): copy forward. */
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
} else {
|
||||
/* Overlap: copy backward. */
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--)
|
||||
*--d = *--s;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int memcmp(const void *a, const void *b, size_t n)
|
||||
{
|
||||
const unsigned char *x = a;
|
||||
const unsigned char *y = b;
|
||||
while (n--) {
|
||||
if (*x != *y)
|
||||
return *x - *y;
|
||||
x++;
|
||||
y++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *dst, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = dst;
|
||||
while (n--)
|
||||
*d++ = (unsigned char)c;
|
||||
return dst;
|
||||
}
|
||||
Reference in New Issue
Block a user