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]>
106 lines
2.1 KiB
C
106 lines
2.1 KiB
C
/*
|
|
* 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;
|
|
}
|