At least define a bunch of libc stuff
This commit is contained in:
parent
416ae2d1a3
commit
a283332be6
@ -10,4 +10,6 @@ extern double fabs(double x);
|
||||
extern double sin(double x);
|
||||
extern double cos(double x);
|
||||
|
||||
double frexp(double x, int *exp);
|
||||
|
||||
#define HUGE_VAL (__builtin_huge_val())
|
||||
|
@ -22,6 +22,7 @@ extern int fclose(FILE * stream);
|
||||
extern int fseek(FILE * stream, long offset, int whence);
|
||||
extern long ftell(FILE * stream);
|
||||
extern FILE * fdopen(int fd, const char *mode);
|
||||
extern FILE * freopen(const char *path, const char *mode, FILE * stream);
|
||||
|
||||
extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream);
|
||||
extern size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream);
|
||||
@ -50,7 +51,18 @@ extern int ungetc(int c, FILE * stream);
|
||||
|
||||
extern int feof(FILE * stream);
|
||||
extern void clearerr(FILE * stream);
|
||||
extern int ferror(FILE * stream);
|
||||
|
||||
extern char * strerror(int errnum);
|
||||
|
||||
extern int _fwouldblock(FILE * stream);
|
||||
|
||||
extern FILE * tmpfile(void);
|
||||
|
||||
extern int setvbuf(FILE * stream, char * buf, int mode, size_t size);
|
||||
|
||||
#define _IONBF 0
|
||||
#define _IOLBF 1
|
||||
#define _IOFBF 2
|
||||
|
||||
#define getc(s) fgetc(s)
|
||||
|
@ -19,6 +19,7 @@ extern int abs(int j);
|
||||
extern int putenv(char * name);
|
||||
extern int setenv(const char *name, const char *value, int overwrite);
|
||||
|
||||
extern double strtod(const char *nptr, char **endptr);
|
||||
extern double atof(const char * nptr);
|
||||
extern int atoi(const char * nptr);
|
||||
extern long atol(const char * nptr);
|
||||
|
@ -26,6 +26,7 @@ extern char * strstr(const char * h, const char * n);
|
||||
|
||||
extern int strcmp(const char * l, const char * r);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
extern int strcoll(const char * s1, const char * s2);
|
||||
|
||||
extern size_t strcspn(const char * s, const char * c);
|
||||
extern size_t strspn(const char * s, const char * c);
|
||||
@ -38,3 +39,5 @@ extern char * strcat(char *dest, const char *src);
|
||||
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
|
||||
|
||||
extern char * strncpy(char *dest, const char *src, size_t n);
|
||||
|
||||
extern char * strerror(int errnum);
|
||||
|
@ -19,3 +19,6 @@ extern struct tm *localtime(const time_t *timep);
|
||||
extern size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
|
||||
extern time_t time(time_t * out);
|
||||
extern double difftime(time_t a, time_t b);
|
||||
|
||||
extern int clock(void);
|
||||
#define CLOCKS_PER_SEC 1
|
||||
|
@ -54,6 +54,8 @@ extern int getopt(int argc, char * const argv[], const char * optstring);
|
||||
extern char * optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
extern int unlink(const char * pathname);
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
@ -38,7 +38,6 @@ DEFN_SYSCALL3(ioctl, 47, int, int, void *);
|
||||
DEFN_SYSCALL2(access, 48, char *, int);
|
||||
DEFN_SYSCALL2(stat, 49, char *, void *);
|
||||
DEFN_SYSCALL1(umask, 51, int);
|
||||
DEFN_SYSCALL1(unlink, 52, char *);
|
||||
DEFN_SYSCALL3(waitpid, 53, int, int *, int);
|
||||
DEFN_SYSCALL5(mount, SYS_MOUNT, char *, char *, char *, unsigned long, void *);
|
||||
DEFN_SYSCALL2(lstat, SYS_LSTAT, char *, void *);
|
||||
|
25
libc/math/frexp.c
Normal file
25
libc/math/frexp.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
double frexp(double x, int *exp) {
|
||||
struct {
|
||||
uint32_t lsw;
|
||||
uint32_t msw;
|
||||
} extract;
|
||||
|
||||
memcpy(&extract, &x, sizeof(double));
|
||||
|
||||
*exp = ((extract.msw & 0x7ff00000) >> 20) - 0x3FE;
|
||||
|
||||
struct {
|
||||
uint32_t lsw;
|
||||
uint32_t msw;
|
||||
} out_double;
|
||||
|
||||
out_double.msw = (extract.msw & 0x800fffff) | 0x3FE00000;
|
||||
out_double.lsw = extract.lsw;
|
||||
|
||||
double out;
|
||||
memcpy(&out, &out_double, sizeof(double));
|
||||
return out;
|
||||
}
|
@ -16,6 +16,7 @@ struct _FILE {
|
||||
int read_from;
|
||||
int ungetc;
|
||||
int eof;
|
||||
int bufsiz;
|
||||
};
|
||||
|
||||
FILE _stdin = {
|
||||
@ -26,6 +27,7 @@ FILE _stdin = {
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
.eof = 0,
|
||||
.bufsiz = BUFSIZ,
|
||||
};
|
||||
|
||||
FILE _stdout = {
|
||||
@ -36,6 +38,7 @@ FILE _stdout = {
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
.eof = 0,
|
||||
.bufsiz = BUFSIZ,
|
||||
};
|
||||
|
||||
FILE _stderr = {
|
||||
@ -46,6 +49,7 @@ FILE _stderr = {
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
.eof = 0,
|
||||
.bufsiz = BUFSIZ,
|
||||
};
|
||||
|
||||
FILE * stdin = &_stdin;
|
||||
@ -71,6 +75,18 @@ static char * stream_id(FILE * stream) {
|
||||
|
||||
extern char * _argv_0;
|
||||
|
||||
int setvbuf(FILE * stream, char * buf, int mode, size_t size) {
|
||||
if (mode != _IOLBF) {
|
||||
return -1; /* Unsupported */
|
||||
}
|
||||
if (buf) {
|
||||
if (stream->read_buf) {
|
||||
free(stream->read_buf);
|
||||
}
|
||||
stream->bufsiz = size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t read_bytes(FILE * f, char * out, size_t len) {
|
||||
size_t r_out = 0;
|
||||
@ -89,10 +105,10 @@ static size_t read_bytes(FILE * f, char * out, size_t len) {
|
||||
}
|
||||
|
||||
if (f->available == 0) {
|
||||
if (f->offset == BUFSIZ) {
|
||||
if (f->offset == f->bufsiz) {
|
||||
f->offset = 0;
|
||||
}
|
||||
ssize_t r = read(fileno(f), &f->read_buf[f->offset], BUFSIZ - f->offset);
|
||||
ssize_t r = read(fileno(f), &f->read_buf[f->offset], f->bufsiz - f->offset);
|
||||
if (r < 0) {
|
||||
//fprintf(stderr, "error condition\n");
|
||||
return r_out;
|
||||
@ -125,8 +141,7 @@ static size_t read_bytes(FILE * f, char * out, size_t len) {
|
||||
return r_out;
|
||||
}
|
||||
|
||||
FILE * fopen(const char *path, const char *mode) {
|
||||
|
||||
static void parse_mode(const char * mode, int * flags_, int * mask_) {
|
||||
const char * x = mode;
|
||||
|
||||
int flags = 0;
|
||||
@ -152,6 +167,15 @@ FILE * fopen(const char *path, const char *mode) {
|
||||
++x;
|
||||
}
|
||||
|
||||
*flags_ = flags;
|
||||
*mask_ = mask;
|
||||
}
|
||||
|
||||
|
||||
FILE * fopen(const char *path, const char *mode) {
|
||||
|
||||
int flags, mask;
|
||||
parse_mode(mode, &flags, &mask);
|
||||
int fd = syscall_open(path, flags, mask);
|
||||
|
||||
if (fd < 0) {
|
||||
@ -161,6 +185,7 @@ FILE * fopen(const char *path, const char *mode) {
|
||||
FILE * out = malloc(sizeof(FILE));
|
||||
out->fd = fd;
|
||||
out->read_buf = malloc(BUFSIZ);
|
||||
out->bufsiz = BUFSIZ;
|
||||
out->available = 0;
|
||||
out->read_from = 0;
|
||||
out->offset = 0;
|
||||
@ -170,6 +195,30 @@ FILE * fopen(const char *path, const char *mode) {
|
||||
return out;
|
||||
}
|
||||
|
||||
/* This is very wrong */
|
||||
FILE * freopen(const char *path, const char *mode, FILE * stream) {
|
||||
|
||||
if (path) {
|
||||
if (stream) {
|
||||
fclose(stream);
|
||||
}
|
||||
int flags, mask;
|
||||
parse_mode(mode, &flags, &mask);
|
||||
int fd = syscall_open(path, flags, mask);
|
||||
stream->fd = fd;
|
||||
stream->available = 0;
|
||||
stream->read_from = 0;
|
||||
stream->offset = 0;
|
||||
stream->ungetc = -1;
|
||||
stream->eof = 0;
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
int ungetc(int c, FILE * stream) {
|
||||
if (stream->ungetc > 0)
|
||||
return EOF;
|
||||
@ -181,6 +230,7 @@ FILE * fdopen(int fd, const char *mode){
|
||||
FILE * out = malloc(sizeof(FILE));
|
||||
out->fd = fd;
|
||||
out->read_buf = malloc(BUFSIZ);
|
||||
out->bufsiz = BUFSIZ;
|
||||
out->available = 0;
|
||||
out->read_from = 0;
|
||||
out->offset = 0;
|
||||
@ -339,3 +389,7 @@ int feof(FILE * stream) {
|
||||
void clearerr(FILE * stream) {
|
||||
stream->eof = 0;
|
||||
}
|
||||
|
||||
int ferror(FILE * stream) {
|
||||
return 0; /* TODO */
|
||||
}
|
||||
|
15
libc/stdio/tmpfile.c
Normal file
15
libc/stdio/tmpfile.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
FILE * tmpfile(void) {
|
||||
static int tmpfile_num = 1;
|
||||
|
||||
char tmp[100];
|
||||
sprintf(tmp, "/tmp/tmp%d.%d", getpid(), tmpfile_num++);
|
||||
|
||||
FILE * out = fopen(tmp, "w+b");
|
||||
|
||||
unlink(tmp);
|
||||
|
||||
return out;
|
||||
}
|
@ -3,39 +3,5 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
double atof(const char * nptr) {
|
||||
int sign = 1;
|
||||
if (*nptr == '-') {
|
||||
sign = -1;
|
||||
nptr++;
|
||||
}
|
||||
|
||||
long long decimal_part = 0;
|
||||
|
||||
while (*nptr && *nptr != '.') {
|
||||
if (*nptr < '0' || *nptr > '9') {
|
||||
return 0.0;
|
||||
}
|
||||
decimal_part *= 10LL;
|
||||
decimal_part += (long long)(*nptr - '0');
|
||||
nptr++;
|
||||
}
|
||||
|
||||
double sub_part = 0;
|
||||
double multiplier = 0.1;
|
||||
|
||||
if (*nptr == '.') {
|
||||
nptr++;
|
||||
|
||||
while (*nptr) {
|
||||
if (*nptr < '0' || *nptr > '9') {
|
||||
return ((double)decimal_part) * (double)(sign);
|
||||
}
|
||||
|
||||
sub_part += multiplier * (*nptr - '0');
|
||||
multiplier *= 0.1;
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return ((double)decimal_part + sub_part) * (double)(sign);
|
||||
return strtod(nptr, NULL);
|
||||
}
|
||||
|
49
libc/stdlib/strtod.c
Normal file
49
libc/stdlib/strtod.c
Normal file
@ -0,0 +1,49 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
double strtod(const char *nptr, char **endptr) {
|
||||
int sign = 1;
|
||||
if (*nptr == '-') {
|
||||
sign = -1;
|
||||
nptr++;
|
||||
}
|
||||
|
||||
long long decimal_part = 0;
|
||||
|
||||
while (*nptr && *nptr != '.') {
|
||||
if (*nptr < '0' || *nptr > '9') {
|
||||
if (endptr) {
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
decimal_part *= 10LL;
|
||||
decimal_part += (long long)(*nptr - '0');
|
||||
nptr++;
|
||||
}
|
||||
|
||||
double sub_part = 0;
|
||||
double multiplier = 0.1;
|
||||
|
||||
if (*nptr == '.') {
|
||||
nptr++;
|
||||
|
||||
while (*nptr) {
|
||||
if (*nptr < '0' || *nptr > '9') {
|
||||
if (endptr) {
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
return ((double)decimal_part) * (double)(sign);
|
||||
}
|
||||
|
||||
sub_part += multiplier * (*nptr - '0');
|
||||
multiplier *= 0.1;
|
||||
nptr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (endptr) {
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
return ((double)decimal_part + sub_part) * (double)(sign);
|
||||
}
|
||||
|
@ -51,6 +51,10 @@ int strcmp(const char * l, const char * r) {
|
||||
return *(unsigned char *)l - *(unsigned char *)r;
|
||||
}
|
||||
|
||||
int strcoll(const char * s1, const char * s2) {
|
||||
return strcmp(s1,s2); /* TODO locales */
|
||||
}
|
||||
|
||||
size_t strlen(const char * s) {
|
||||
const char * a = s;
|
||||
const size_t * w;
|
||||
|
126
libc/string/strerror.c
Normal file
126
libc/string/strerror.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
static char * _error_strings[256] = {
|
||||
[EPERM] = "Not super-user",
|
||||
[ENOENT] = "No such file or directory",
|
||||
[ESRCH] = "No such process",
|
||||
[EINTR] = "Interrupted system call",
|
||||
[EIO] = "I/O error",
|
||||
[ENXIO] = "No such device or address",
|
||||
[E2BIG] = "Arg list too long",
|
||||
[ENOEXEC] = "Exec format error",
|
||||
[EBADF] = "Bad file number",
|
||||
[ECHILD] = "No children",
|
||||
[EAGAIN] = "No more processes",
|
||||
[ENOMEM] = "Not enough core",
|
||||
[EACCES] = "Permission denied",
|
||||
[EFAULT] = "Bad address",
|
||||
[ENOTBLK] = "Block device required",
|
||||
[EBUSY] = "Mount device busy",
|
||||
[EEXIST] = "File exists",
|
||||
[EXDEV] = "Cross-device link",
|
||||
[ENODEV] = "No such device",
|
||||
[ENOTDIR] = "Not a directory",
|
||||
[EISDIR] = "Is a directory",
|
||||
[EINVAL] = "Invalid argument",
|
||||
[ENFILE] = "Too many open files in system",
|
||||
[EMFILE] = "Too many open files",
|
||||
[ENOTTY] = "Not a typewriter",
|
||||
[ETXTBSY] = "Text file busy",
|
||||
[EFBIG] = "File too large",
|
||||
[ENOSPC] = "No space left on device",
|
||||
[ESPIPE] = "Illegal seek",
|
||||
[EROFS] = "Read only file system",
|
||||
[EMLINK] = "Too many links",
|
||||
[EPIPE] = "Broken pipe",
|
||||
[EDOM] = "Math arg out of domain of func",
|
||||
[ERANGE] = "Math result not representable",
|
||||
[ENOMSG] = "No message of desired type",
|
||||
[EIDRM] = "Identifier removed",
|
||||
[ECHRNG] = "Channel number out of range",
|
||||
[EL2NSYNC] = "Level 2 not synchronized",
|
||||
[EL3HLT] = "Level 3 halted",
|
||||
[EL3RST] = "Level 3 reset",
|
||||
[ELNRNG] = "Link number out of range",
|
||||
[EUNATCH] = "Protocol driver not attached",
|
||||
[ENOCSI] = "No CSI structure available",
|
||||
[EL2HLT] = "Level 2 halted",
|
||||
[EDEADLK] = "Deadlock condition",
|
||||
[ENOLCK] = "No record locks available",
|
||||
[EBADE] = "Invalid exchange",
|
||||
[EBADR] = "Invalid request descriptor",
|
||||
[EXFULL] = "Exchange full",
|
||||
[ENOANO] = "No anode",
|
||||
[EBADRQC] = "Invalid request code",
|
||||
[EBADSLT] = "Invalid slot",
|
||||
[EDEADLOCK] = "File locking deadlock error",
|
||||
[EBFONT] = "Bad font file fmt",
|
||||
[ENOSTR] = "Device not a stream",
|
||||
[ENODATA] = "No data (for no delay io)",
|
||||
[ETIME] = "Timer expired",
|
||||
[ENOSR] = "Out of streams resources",
|
||||
[ENONET] = "Machine is not on the network",
|
||||
[ENOPKG] = "Package not installed",
|
||||
[EREMOTE] = "The object is remote",
|
||||
[ENOLINK] = "The link has been severed",
|
||||
[EADV] = "Advertise error",
|
||||
[ESRMNT] = "Srmount error",
|
||||
[ECOMM] = "Communication error on send",
|
||||
[EPROTO] = "Protocol error",
|
||||
[EMULTIHOP] = "Multihop attempted",
|
||||
[ELBIN] = "Inode is remote (not really error)",
|
||||
[EDOTDOT] = "Cross mount point (not really error)",
|
||||
[EBADMSG] = "Trying to read unreadable message",
|
||||
[EFTYPE] = "Inappropriate file type or format",
|
||||
[ENOTUNIQ] = "Given log. name not unique",
|
||||
[EBADFD] = "f.d. invalid for this operation",
|
||||
[EREMCHG] = "Remote address changed",
|
||||
[ELIBACC] = "Can't access a needed shared lib",
|
||||
[ELIBBAD] = "Accessing a corrupted shared lib",
|
||||
[ELIBSCN] = ".lib section in a.out corrupted",
|
||||
[ELIBMAX] = "Attempting to link in too many libs",
|
||||
[ELIBEXEC] = "Attempting to exec a shared library",
|
||||
[ENOSYS] = "Function not implemented",
|
||||
[ENOTEMPTY] = "Directory not empty",
|
||||
[ENAMETOOLONG] = "File or path name too long",
|
||||
[ELOOP] = "Too many symbolic links",
|
||||
[EOPNOTSUPP] = "Operation not supported on transport endpoint",
|
||||
[EPFNOSUPPORT] = "Protocol family not supported",
|
||||
[ECONNRESET] = "Connection reset by peer",
|
||||
[ENOBUFS] = "No buffer space available",
|
||||
[EAFNOSUPPORT] = "Address family not supported by protocol family",
|
||||
[EPROTOTYPE] = "Protocol wrong type for socket",
|
||||
[ENOTSOCK] = "Socket operation on non-socket",
|
||||
[ENOPROTOOPT] = "Protocol not available",
|
||||
[ESHUTDOWN] = "Can't send after socket shutdown",
|
||||
[ECONNREFUSED] = "Connection refused",
|
||||
[EADDRINUSE] = "Address already in use",
|
||||
[ECONNABORTED] = "Connection aborted",
|
||||
[ENETUNREACH] = "Network is unreachable",
|
||||
[ENETDOWN] = "Network interface is not configured",
|
||||
[ETIMEDOUT] = "Connection timed out",
|
||||
[EHOSTDOWN] = "Host is down",
|
||||
[EHOSTUNREACH] = "Host is unreachable",
|
||||
[EINPROGRESS] = "Connection already in progress",
|
||||
[EALREADY] = "Socket already connected",
|
||||
[EDESTADDRREQ] = "Destination address required",
|
||||
[EMSGSIZE] = "Message too long",
|
||||
[EPROTONOSUPPORT] = "Unknown protocol",
|
||||
[ESOCKTNOSUPPORT] = "Socket type not supported",
|
||||
[EADDRNOTAVAIL] = "Address not available",
|
||||
[EISCONN] = "Socket is already connected",
|
||||
[ENOTCONN] = "Socket is not connected",
|
||||
[ENOTSUP] = "Not supported",
|
||||
[EOVERFLOW] = "Value too large for defined data type",
|
||||
[ECANCELED] = "Operation canceled",
|
||||
[ENOTRECOVERABLE] = "State not recoverable",
|
||||
[EOWNERDEAD] = "Previous owner died",
|
||||
[ESTRPIPE] = "Streams pipe error",
|
||||
};
|
||||
|
||||
char * strerror(int errnum) {
|
||||
if (errnum > 255) return "???";
|
||||
if (!_error_strings[errnum]) return "???";
|
||||
return _error_strings[errnum];
|
||||
}
|
5
libc/time/clock.c
Normal file
5
libc/time/clock.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include <time.h>
|
||||
|
||||
int clock(void) {
|
||||
return -1;
|
||||
}
|
16
libc/unistd/unlink.c
Normal file
16
libc/unistd/unlink.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <syscall.h>
|
||||
#include <syscall_nums.h>
|
||||
|
||||
DEFN_SYSCALL1(unlink, SYS_UNLINK, char *);
|
||||
|
||||
int unlink(const char * pathname) {
|
||||
int result = syscall_unlink((char *)pathname);
|
||||
if (result < 0) {
|
||||
errno = -result;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user