libc: split up large .c files, slimming down small binaries a bit

This commit is contained in:
dzwdz 2023-09-03 01:30:53 +02:00
parent fd80c0b227
commit a492c6ec11
15 changed files with 503 additions and 483 deletions

3
src/cmd/true/true.c Normal file
View File

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

View File

@ -36,7 +36,7 @@ _Noreturn void _start2(struct execdata *ed) {
_sys_intr_set(intr_trampoline);
intr_set(intr_default);
__setinitialcwd(ed->cwd);
__initialcwd = ed->cwd;
exit(main(ed->argc, ed->argv, ed->envp));
}

View File

@ -0,0 +1,4 @@
#pragma once
void intr_set(void (*fn)(void));
void intr_default(void);

View File

@ -1,5 +1,6 @@
#pragma once
#include <camellia/types.h> // TODO only needed because of hid_t
#include <camellia/intr.h> // TODO only included for backwards compat
#include <sys/types.h>
#include <getopt.h>
@ -64,8 +65,5 @@ unsigned int sleep(unsigned int seconds);
* @return 0 on failure, length of the path otherwise */
size_t absolutepath(char *out, const char *in, size_t size);
// TODO put in an internal libc header
void __setinitialcwd(const char *c);
void intr_set(void (*fn)(void));
void intr_default(void);
/* used internally */
extern const char *__initialcwd;

13
src/libc/intr.c Normal file
View File

@ -0,0 +1,13 @@
#include <camellia/intr.h>
#include <stdlib.h>
static void intr_null(void) { }
extern void (*volatile _intr)(void);
void intr_set(void (*fn)(void)) {
_intr = fn ? fn : intr_null;
}
void intr_default(void) {
exit(-1);
}

View File

@ -1,27 +1,10 @@
#include <camellia/syscalls.h>
#include <shared/printf.h>
#include <stdio.h>
#include <string.h>
static void backend_file(void *arg, const char *buf, size_t len) {
fwrite(buf, 1, len, arg);
}
int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) {
return __printf_internal(fmt, ap, backend_file, f);
}
int printf(const char *restrict fmt, ...) {
int ret;
va_list argp;
va_start(argp, fmt);
ret = vprintf(fmt, argp);
va_end(argp);
return ret;
}
int fprintf(FILE *restrict f, const char *restrict fmt, ...) {
int ret;
va_list argp;
@ -31,11 +14,15 @@ int fprintf(FILE *restrict f, const char *restrict fmt, ...) {
return ret;
}
int sprintf(char *restrict s, const char *restrict fmt, ...) {
int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) {
return __printf_internal(fmt, ap, backend_file, f);
}
int printf(const char *restrict fmt, ...) {
int ret;
va_list argp;
va_start(argp, fmt);
ret = vsnprintf(s, ~0, fmt, argp);
ret = vprintf(fmt, argp);
va_end(argp);
return ret;
}
@ -43,18 +30,3 @@ int sprintf(char *restrict s, const char *restrict fmt, ...) {
int vprintf(const char *restrict fmt, va_list ap) {
return vfprintf(stdout, fmt, ap);
}
int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) {
return vsnprintf(s, ~0, fmt, ap);
}
int _klogf(const char *fmt, ...) {
char buf[256];
int ret;
va_list argp;
va_start(argp, fmt);
ret = vsnprintf(buf, sizeof buf, fmt, argp);
va_end(argp);
_sys_debug_klog(buf, ret);
return ret;
}

28
src/libc/stdio/sprintf.c Normal file
View File

@ -0,0 +1,28 @@
#include <camellia/syscalls.h>
#include <shared/mem.h>
#include <shared/printf.h>
#include <stdio.h>
int sprintf(char *restrict s, const char *restrict fmt, ...) {
int ret;
va_list argp;
va_start(argp, fmt);
ret = vsnprintf(s, ~0, fmt, argp);
va_end(argp);
return ret;
}
int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) {
return vsnprintf(s, ~0, fmt, ap);
}
int _klogf(const char *fmt, ...) {
char buf[256];
int ret;
va_list argp;
va_start(argp, fmt);
ret = vsnprintf(buf, sizeof buf, fmt, argp);
va_end(argp);
_sys_debug_klog(buf, ret);
return ret;
}

View File

@ -0,0 +1,28 @@
#include <_proc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const char *progname;
const char *getprogname(void) {
return progname;
}
void setprogname(const char *pg) {
progname = pg;
setproctitle(NULL);
}
void setproctitle(const char *fmt, ...) {
// TODO bounds checking
if (!fmt) {
strcpy(_psdata_loc->desc, progname);
return;
}
sprintf(_psdata_loc->desc, "%s: ", progname);
va_list argp;
va_start(argp, fmt);
vsnprintf(_psdata_loc->desc + strlen(_psdata_loc->desc), 128, fmt, argp);
va_end(argp);
}

View File

@ -1,4 +1,3 @@
#include <_proc.h>
#include <bits/panic.h>
#include <camellia.h>
#include <camellia/syscalls.h>
@ -10,29 +9,6 @@ _Noreturn void abort(void) {
_sys_exit(1);
}
static const char *progname;
const char *getprogname(void) {
return progname;
}
void setprogname(const char *pg) {
progname = pg;
setproctitle(NULL);
}
void setproctitle(const char *fmt, ...) {
// TODO bounds checking
if (!fmt) {
strcpy(_psdata_loc->desc, progname);
return;
}
sprintf(_psdata_loc->desc, "%s: ", progname);
va_list argp;
va_start(argp, fmt);
vsnprintf(_psdata_loc->desc + strlen(_psdata_loc->desc), 128, fmt, argp);
va_end(argp);
}
char *mktemp(char *tmpl) {
// TODO mktemp mkstemp
return tmpl;

105
src/libc/string/basic.c Normal file
View File

@ -0,0 +1,105 @@
/** String functions that don't depend on any external functions. */
#include <string.h>
char *strchr(const char *s, int c) {
for (; *s || c == 0; s++) {
if (*s == c) return (char *)s;
}
return NULL;
}
char *strrchr(const char *s, int c) {
for (int i = strlen(s) + 1; i >= 0; i--) {
if (s[i] == c) return (char *)s + i;
}
return NULL;
}
size_t strspn(const char *s, const char *accept) {
size_t l = 0;
for (; s[l] && strchr(accept, s[l]); l++);
return l;
}
size_t strcspn(const char *s, const char *reject) {
size_t l = 0;
for (; s[l] && !strchr(reject, s[l]); l++);
return l;
}
char *strpbrk(const char *s1, const char *s2) {
for (; *s1; s1++) {
if (strchr(s2, *s1)) return (char*)s1;
}
return NULL;
}
char *strtok(char *restrict s, const char *restrict sep) {
static char *state;
return strtok_r(s, sep, &state);
}
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state) {
char *end;
if (!s) s = *state;
s += strspn(s, sep); /* beginning of token */
if (!*s) return NULL;
end = s + strcspn(s, sep);
if (*end) {
*end = '\0';
*state = end + 1;
} else {
*state = end;
}
return s;
}
int strncmp(const char *s1, const char *s2, size_t n) {
for (size_t i = 0; i < n; i++) {
if (s1[i] < s2[i]) return -1;
if (s1[i] > s2[i]) return 1;
}
return 0;
}
int strcoll(const char *s1, const char *s2) {
return strcmp(s1, s2);
}
char *strstr(const char *s1, const char *s2) {
size_t l1 = strlen(s1), l2 = strlen(s2);
for (; l2 <= l1; s1++, l1--) {
if (memcmp(s1, s2, l2) == 0) return (char*)s1;
}
return NULL;
}
char *strcat(char *restrict dst, const char *restrict src) {
return strcpy(dst + strlen(dst), src);
}
char *strcpy(char *restrict s1, const char *restrict s2) {
char *ret = s1;
while (*s2) *s1++ = *s2++;
*s1 = *s2;
return ret;
}
char *strncpy(char *restrict dst, const char *restrict src, size_t n) {
for (size_t i = 0; i < n; i++) {
dst[i] = src[i];
if (dst[i] == '\0') return dst + i; // TODO fill with null bytes
}
return dst;
}
size_t strnlen(const char *s, size_t len) {
for (size_t i = 0; i < len; i++) {
if (!s[i]) {
return i;
}
}
return len;
}

View File

@ -1,3 +1,5 @@
/** String functions that don't fit into any of the other .c files */
#include <bits/panic.h>
#include <ctype.h>
#include <errno.h>
@ -5,107 +7,14 @@
#include <string.h>
#include <strings.h>
char *strchr(const char *s, int c) {
for (; *s || c == 0; s++) {
if (*s == c) return (char *)s;
}
return NULL;
}
char *strrchr(const char *s, int c) {
for (int i = strlen(s) + 1; i >= 0; i--) {
if (s[i] == c) return (char *)s + i;
}
return NULL;
}
size_t strspn(const char *s, const char *accept) {
size_t l = 0;
for (; s[l] && strchr(accept, s[l]); l++);
return l;
}
size_t strcspn(const char *s, const char *reject) {
size_t l = 0;
for (; s[l] && !strchr(reject, s[l]); l++);
return l;
}
char *strpbrk(const char *s1, const char *s2) {
for (; *s1; s1++) {
if (strchr(s2, *s1)) return (char*)s1;
}
return NULL;
}
char *strtok(char *restrict s, const char *restrict sep) {
static char *state;
return strtok_r(s, sep, &state);
}
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state) {
char *end;
if (!s) s = *state;
s += strspn(s, sep); /* beginning of token */
if (!*s) return NULL;
end = s + strcspn(s, sep);
if (*end) {
*end = '\0';
*state = end + 1;
} else {
*state = end;
}
return s;
}
int strncmp(const char *s1, const char *s2, size_t n) {
for (size_t i = 0; i < n; i++) {
if (s1[i] < s2[i]) return -1;
if (s1[i] > s2[i]) return 1;
}
return 0;
}
int strcoll(const char *s1, const char *s2) {
return strcmp(s1, s2);
}
// TODO implement strstr using Boyer-Moore
char *strstr(const char *s1, const char *s2) {
size_t l1 = strlen(s1), l2 = strlen(s2);
for (; l2 <= l1; s1++, l1--) {
if (memcmp(s1, s2, l2) == 0) return (char*)s1;
}
return NULL;
}
char *strcat(char *restrict dst, const char *restrict src) {
return strcpy(dst + strlen(dst), src);
}
char *strcpy(char *restrict s1, const char *restrict s2) {
char *ret = s1;
while (*s2) *s1++ = *s2++;
*s1 = *s2;
return ret;
}
char *strncpy(char *restrict dst, const char *restrict src, size_t n) {
for (size_t i = 0; i < n; i++) {
dst[i] = src[i];
if (dst[i] == '\0') return dst + i; // TODO fill with null bytes
}
return dst;
}
char *strncat(char *restrict dst, const char *restrict src, size_t n) {
(void)dst; (void)src; (void)n;
__libc_panic("unimplemented");
}
char *stpncpy(char *restrict dst, const char *restrict src, size_t n) {
return stpncpy(dst, src, n) + n;
(void)dst; (void)src; (void)n;
__libc_panic("unimplemented");
}
char *strdup(const char *s) {
@ -115,15 +24,6 @@ char *strdup(const char *s) {
return buf;
}
size_t strnlen(const char *s, size_t len) {
for (size_t i = 0; i < len; i++) {
if (!s[i]) {
return i;
}
}
return len;
}
char *strsignal(int sig) {
static char buf[32];
snprintf(buf, sizeof(buf), "signal %d", sig);

View File

@ -1,315 +0,0 @@
#include <bits/panic.h>
#include <camellia.h>
#include <camellia/path.h>
#include <camellia/syscalls.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <elfload.h>
int errno = 0;
static char *_environ[] = {NULL};
char **environ = _environ;
int fork(void) {
return _sys_fork(0, NULL);
}
pid_t vfork(void) {
// TODO vfork is implemented improperly and will break stuff
return _sys_fork(0, NULL);
}
int close(hid_t h) {
return _sys_close(h);
}
_Noreturn void exit(int c) {
_sys_exit(c);
}
_Noreturn void _exit(int c) { exit(c); };
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize) {
(void)path; (void)buf; (void)bufsize;
errno = ENOSYS;
return -1;
}
int link(const char *path1, const char *path2) {
(void)path1; (void)path2;
errno = ENOSYS;
return -1;
}
int unlink(const char *path) {
hid_t h = camellia_open(path, OPEN_WRITE);
if (h < 0) return errno = -h, -1;
long ret = _sys_remove(h);
if (ret < 0) return errno = -ret, -1;
return 0;
}
int rmdir(const char *path) {
(void)path;
__libc_panic("unimplemented");
}
int symlink(const char *path1, const char *path2) {
(void)path1; (void)path2;
errno = ENOSYS;
return -1;
}
// TODO isatty
int isatty(int fd) {
return fd <= 2 ? 1 : 0;
}
int execv(const char *path, char *const argv[]) {
return execve(path, argv, NULL);
}
int execvp(const char *path, char *const argv[]) {
// TODO execvp
return execve(path, argv, NULL);
}
int execvpe(const char *path, char *const argv[], char *const envp[]) {
if (path[0] != '/') {
char *exp = malloc(strlen(path) + 6);
int ret;
strcpy(exp, "/bin/");
strcat(exp, path);
ret = execve(exp, argv, envp);
free(exp);
return ret;
}
return execve(path, argv, envp);
}
int execve(const char *path, char *const argv[], char *const envp[]) {
FILE *file = fopen(path, "e");
char hdr[4] = {0};
if (!file)
return -1;
fread(hdr, 1, 4, file);
fseek(file, 0, SEEK_SET);
if (!memcmp("\x7f""ELF", hdr, 4)) {
elf_execf(file, (void*)argv, (void*)envp);
fclose(file);
} else if (!memcmp("#!", hdr, 2)) {
char buf[256];
fseek(file, 2, SEEK_SET);
if (fgets(buf, sizeof buf, file)) {
const char *argv [] = {buf, path, NULL};
char *endl = strchr(buf, '\n');
if (endl) *endl = '\0';
execve(buf, (void*)argv, envp);
}
}
errno = EINVAL;
return -1;
}
static const char *__initialcwd;
static char *cwd = NULL, *cwd2 = NULL;
static size_t cwdcapacity = 0;
static const char *getrealcwd(void) {
/* __initialcwd can't just be initialized with "/" because ld has seemingly
* started to revolt against humanity and not process half the relocations
* it sees. */
if (cwd) return cwd;
if (__initialcwd) return __initialcwd;
return "/";
}
int chdir(const char *path) {
hid_t h;
char *tmp;
size_t len = absolutepath(NULL, path, 0) + 1; /* +1 for the trailing slash */
if (cwdcapacity < len) {
cwdcapacity = len;
if (cwd) {
cwd = realloc(cwd, len);
cwd2 = realloc(cwd2, len);
} else {
size_t initlen = strlen(__initialcwd) + 1;
if (len < initlen)
len = initlen;
cwd = malloc(initlen);
cwd2 = malloc(initlen);
memcpy(cwd, __initialcwd, initlen);
}
}
absolutepath(cwd2, path, cwdcapacity);
len = strlen(cwd2);
if (cwd2[len - 1] != '/') {
cwd2[len] = '/';
cwd2[len + 1] = '\0';
}
/* check if exists */
h = camellia_open(cwd2, OPEN_READ);
if (h < 0) return errno = ENOENT, -1;
close(h);
tmp = cwd;
cwd = cwd2;
cwd2 = tmp;
return 0;
}
char *getcwd(char *buf, size_t capacity) {
const char *realcwd = getrealcwd();
size_t len = strlen(realcwd) + 1;
if (capacity < len) {
errno = capacity == 0 ? EINVAL : ERANGE;
return NULL;
}
memcpy(buf, realcwd, len);
return buf;
}
uid_t getuid(void) { return 0; }
uid_t geteuid(void) { return 0; }
gid_t getgid(void) { return 0; }
gid_t getegid(void) { return 0; }
int access(const char *path, int mode) {
// TODO impl access()
(void)path; (void)mode;
return 0;
}
int chown(const char *path, uid_t owner, gid_t group) {
(void)path; (void)owner; (void)group;
errno = ENOSYS;
return -1;
}
int setpgid(pid_t pid, pid_t pgid) {
(void)pid; (void)pgid;
return errno = ENOSYS, -1;
}
pid_t tcgetpgrp(int fd) {
(void)fd;
return errno = ENOSYS, -1;
}
int tcsetpgrp(int fd, pid_t pgrp) {
(void)fd; (void)pgrp;
return errno = ENOSYS, -1;
}
pid_t getpgrp(void) {
__libc_panic("unimplemented");
}
pid_t getpid(void) {
return _sys_getpid();
}
pid_t getppid(void) {
return _sys_getppid();
}
int getgroups(int size, gid_t list[]) {
(void)size; (void)list;
__libc_panic("unimplemented");
}
ssize_t read(int fd, void *buf, size_t count) {
// TODO real file descriptor emulation - store offsets
return _sys_read(fd, buf, count, -1);
}
ssize_t write(int fd, const void *buf, size_t count) {
// TODO real file descriptor emulation - store offsets
return _sys_write(fd, buf, count, -1, 0);
}
int pipe(int pipefd[2]) {
// TODO pipe buffering
int ret = _sys_pipe(pipefd, 0);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
int dup(int oldfd) {
(void)oldfd;
__libc_panic("unimplemented");
}
int dup2(int oldfd, int newfd) {
int ret = _sys_dup(oldfd, newfd, 0);
if (ret < 0) {
errno = -ret;
ret = -1;
}
return ret;
}
unsigned int sleep(unsigned int seconds) {
_sys_sleep(seconds * 1000);
return 0;
}
size_t absolutepath(char *out, const char *in, size_t size) {
const char *realcwd = getrealcwd();
size_t len, pos = 0;
if (!in) return strlen(realcwd) + 1;
if (!(in[0] == '/')) {
len = strlen(realcwd);
if (pos + len <= size && out != realcwd)
memcpy(out + pos, realcwd, len);
pos += len;
if (realcwd[len - 1] != '/') {
if (pos + 1 <= size) out[pos] = '/';
pos++;
}
}
len = strlen(in);
if (pos + len <= size)
memcpy(out + pos, in, len);
pos += len;
if (pos <= size) {
pos = path_simplify(out, out, pos);
if (pos == 0) return 0;
}
if (pos + 1 <= size) out[pos] = '\0';
pos++;
return pos;
}
void __setinitialcwd(const char *s) {
__initialcwd = s;
}
static void intr_null(void) { }
extern void (*volatile _intr)(void);
void intr_set(void (*fn)(void)) {
_intr = fn ? fn : intr_null;
}
void intr_default(void) {
exit(-1);
}

95
src/libc/unistd/cwd.c Normal file
View File

@ -0,0 +1,95 @@
#include <camellia.h>
#include <camellia/path.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char *cwd = NULL, *cwd2 = NULL;
static size_t cwdcapacity = 0;
static const char *getrealcwd(void) {
if (cwd) return cwd;
if (__initialcwd) return __initialcwd;
return "/";
}
int chdir(const char *path) {
hid_t h;
char *tmp;
size_t len = absolutepath(NULL, path, 0) + 1; /* +1 for the trailing slash */
if (cwdcapacity < len) {
cwdcapacity = len;
if (cwd) {
cwd = realloc(cwd, len);
cwd2 = realloc(cwd2, len);
} else {
size_t initlen = strlen(__initialcwd) + 1;
if (len < initlen)
len = initlen;
cwd = malloc(initlen);
cwd2 = malloc(initlen);
memcpy(cwd, __initialcwd, initlen);
}
}
absolutepath(cwd2, path, cwdcapacity);
len = strlen(cwd2);
if (cwd2[len - 1] != '/') {
cwd2[len] = '/';
cwd2[len + 1] = '\0';
}
/* check if exists */
h = camellia_open(cwd2, OPEN_READ);
if (h < 0) return errno = ENOENT, -1;
close(h);
tmp = cwd;
cwd = cwd2;
cwd2 = tmp;
return 0;
}
char *getcwd(char *buf, size_t capacity) {
const char *realcwd = getrealcwd();
size_t len = strlen(realcwd) + 1;
if (capacity < len) {
errno = capacity == 0 ? EINVAL : ERANGE;
return NULL;
}
memcpy(buf, realcwd, len);
return buf;
}
size_t absolutepath(char *out, const char *in, size_t size) {
const char *realcwd = getrealcwd();
size_t len, pos = 0;
if (!in) return strlen(realcwd) + 1;
if (!(in[0] == '/')) {
len = strlen(realcwd);
if (pos + len <= size && out != realcwd)
memcpy(out + pos, realcwd, len);
pos += len;
if (realcwd[len - 1] != '/') {
if (pos + 1 <= size) out[pos] = '/';
pos++;
}
}
len = strlen(in);
if (pos + len <= size)
memcpy(out + pos, in, len);
pos += len;
if (pos <= size) {
pos = path_simplify(out, out, pos);
if (pos == 0) return 0;
}
if (pos + 1 <= size) out[pos] = '\0';
pos++;
return pos;
}

128
src/libc/unistd/simple.c Normal file
View File

@ -0,0 +1,128 @@
/** Functions from unistd.h that are either just a syscall or a return. */
#include <camellia/syscalls.h>
#include <errno.h>
#include <unistd.h>
int errno = 0;
static char *_environ[] = {NULL};
char **environ = _environ;
const char *__initialcwd = NULL;
int fork(void) {
return _sys_fork(0, NULL);
}
pid_t vfork(void) {
// TODO vfork is implemented improperly and will break stuff
return _sys_fork(0, NULL);
}
int close(hid_t h) {
return _sys_close(h);
}
_Noreturn void exit(int c) {
_sys_exit(c);
}
_Noreturn void _exit(int c) {
exit(c);
};
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize) {
(void)path; (void)buf; (void)bufsize;
errno = ENOSYS;
return -1;
}
int link(const char *path1, const char *path2) {
(void)path1; (void)path2;
errno = ENOSYS;
return -1;
}
int symlink(const char *path1, const char *path2) {
(void)path1; (void)path2;
errno = ENOSYS;
return -1;
}
// TODO isatty
int isatty(int fd) {
return fd <= 2 ? 1 : 0;
}
uid_t getuid(void) { return 0; }
uid_t geteuid(void) { return 0; }
gid_t getgid(void) { return 0; }
gid_t getegid(void) { return 0; }
int access(const char *path, int mode) {
// TODO impl access()
(void)path; (void)mode;
return 0;
}
int chown(const char *path, uid_t owner, gid_t group) {
(void)path; (void)owner; (void)group;
errno = ENOSYS;
return -1;
}
int setpgid(pid_t pid, pid_t pgid) {
(void)pid; (void)pgid;
return errno = ENOSYS, -1;
}
pid_t tcgetpgrp(int fd) {
(void)fd;
return errno = ENOSYS, -1;
}
int tcsetpgrp(int fd, pid_t pgrp) {
(void)fd; (void)pgrp;
return errno = ENOSYS, -1;
}
pid_t getpid(void) {
return _sys_getpid();
}
pid_t getppid(void) {
return _sys_getppid();
}
ssize_t read(int fd, void *buf, size_t count) {
// TODO real file descriptor emulation - store offsets
// TODO errno
return _sys_read(fd, buf, count, -1);
}
ssize_t write(int fd, const void *buf, size_t count) {
// TODO real file descriptor emulation - store offsets
return _sys_write(fd, buf, count, -1, 0);
}
int pipe(int pipefd[2]) {
// TODO pipe buffering
int ret = _sys_pipe(pipefd, 0);
if (ret < 0) {
errno = -ret;
return -1;
}
return 0;
}
int dup2(int oldfd, int newfd) {
int ret = _sys_dup(oldfd, newfd, 0);
if (ret < 0) {
errno = -ret;
ret = -1;
}
return ret;
}
unsigned int sleep(unsigned int seconds) {
_sys_sleep(seconds * 1000);
return 0;
}

85
src/libc/unistd/unistd.c Normal file
View File

@ -0,0 +1,85 @@
#include <bits/panic.h>
#include <camellia.h>
#include <camellia/syscalls.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <elfload.h>
int unlink(const char *path) {
hid_t h = camellia_open(path, OPEN_WRITE);
if (h < 0) return errno = -h, -1;
long ret = _sys_remove(h);
if (ret < 0) return errno = -ret, -1;
return 0;
}
int rmdir(const char *path) {
(void)path;
__libc_panic("unimplemented");
}
int execv(const char *path, char *const argv[]) {
return execve(path, argv, NULL);
}
int execvp(const char *path, char *const argv[]) {
// TODO execvp
return execve(path, argv, NULL);
}
int execvpe(const char *path, char *const argv[], char *const envp[]) {
if (path[0] != '/') {
char *exp = malloc(strlen(path) + 6);
int ret;
strcpy(exp, "/bin/");
strcat(exp, path);
ret = execve(exp, argv, envp);
free(exp);
return ret;
}
return execve(path, argv, envp);
}
int execve(const char *path, char *const argv[], char *const envp[]) {
FILE *file = fopen(path, "e");
char hdr[4] = {0};
if (!file)
return -1;
fread(hdr, 1, 4, file);
fseek(file, 0, SEEK_SET);
if (!memcmp("\x7f""ELF", hdr, 4)) {
elf_execf(file, (void*)argv, (void*)envp);
fclose(file);
} else if (!memcmp("#!", hdr, 2)) {
char buf[256];
fseek(file, 2, SEEK_SET);
if (fgets(buf, sizeof buf, file)) {
const char *argv [] = {buf, path, NULL};
char *endl = strchr(buf, '\n');
if (endl) *endl = '\0';
execve(buf, (void*)argv, envp);
}
}
errno = EINVAL;
return -1;
}
pid_t getpgrp(void) {
__libc_panic("unimplemented");
}
int getgroups(int size, gid_t list[]) {
(void)size; (void)list;
__libc_panic("unimplemented");
}
int dup(int oldfd) {
(void)oldfd;
__libc_panic("unimplemented");
}