Implemented lots of new functions
This commit is contained in:
@@ -25,7 +25,7 @@ set(CMAKE_EXE_LINKER_FLAGS
|
||||
|
||||
set(malloc_impl dlmalloc)
|
||||
set(photon_libc_sources "")
|
||||
set(generic_dirs string stdio stdlib errno internal)
|
||||
set(generic_dirs string stdio stdlib errno internal ctype)
|
||||
|
||||
message(STATUS "Memory allocator: ${malloc_impl}")
|
||||
|
||||
|
||||
46
photon/libc/ctype/ctype.c
Normal file
46
photon/libc/ctype/ctype.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
static unsigned int random_seed = 53455346;
|
||||
|
||||
int isupper(int c) { return (c >= 65 && c <= 90); }
|
||||
|
||||
int islower(int c) { return (c >= 97 && c <= 122); }
|
||||
|
||||
int toupper(int c) {
|
||||
if (!islower(c)) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return c - 32;
|
||||
}
|
||||
|
||||
int tolower(int c) {
|
||||
if (!isupper(c)) {
|
||||
return c;
|
||||
}
|
||||
|
||||
return c + 32;
|
||||
}
|
||||
|
||||
int isdigit(int c) { return (c >= 48 && c <= 57); }
|
||||
|
||||
int isalpha(int c) { return (c >= 65 && c <= 90) || (c >= 97 && c <= 122); }
|
||||
|
||||
int isalnum(int c) { return isalpha(c) | isdigit(c); }
|
||||
|
||||
int iscntrl(int c) { return (c <= 31) || (c == 127); }
|
||||
|
||||
int isprint(int c) { return (c >= 32 && c <= 126) || (c >= 128 && c <= 254); }
|
||||
|
||||
int isgraph(int c) { return isprint(c) && c != 32; }
|
||||
|
||||
int ispunct(int c) { return isgraph(c) && !isalnum(c); }
|
||||
|
||||
int isspace(int c) {
|
||||
return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\v') ||
|
||||
(c == '\f') || (c == '\r');
|
||||
}
|
||||
|
||||
int isxdigit(int c) {
|
||||
return isdigit(c) || (c >= 65 && c <= 70) || (c >= 97 && c <= 102);
|
||||
}
|
||||
27
photon/libc/include/ctype.h
Normal file
27
photon/libc/include/ctype.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef TYPES_H_
|
||||
#define TYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int isalnum(int c);
|
||||
extern int isalpha(int c);
|
||||
extern int iscntrl(int c);
|
||||
extern int isdigit(int c);
|
||||
extern int isgraph(int c);
|
||||
extern int islower(int c);
|
||||
extern int isprint(int c);
|
||||
extern int ispunct(int c);
|
||||
extern int isspace(int c);
|
||||
extern int isupper(int c);
|
||||
extern int isxdigit(int c);
|
||||
extern int tolower(int c);
|
||||
extern int toupper(int c);
|
||||
extern int fill_random(unsigned char *buffer, unsigned int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
24
photon/libc/include/limits.h
Normal file
24
photon/libc/include/limits.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef LIMITS_H_
|
||||
#define LIMITS_H_
|
||||
|
||||
#define CHAR_BIT 8
|
||||
#define SCHAR_MIN -127
|
||||
#define SCHAR_MAX 127
|
||||
#define UCHAR_MAX 255
|
||||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
#define MB_LEN_MAX 1
|
||||
#define SHRT_MIN -32767
|
||||
#define SHRT_MAX 32767
|
||||
#define USHRT_MAX 65535
|
||||
#define INT_MIN -2147483648
|
||||
#define INT_MAX 2147483648
|
||||
#define UINT_MAX 4294967295
|
||||
#define LONG_MIN -2147483648
|
||||
#define LONG_MAX 2147483648
|
||||
#define ULONG_MAX 4294967295
|
||||
#define _I64_MIN -9223372036854775808
|
||||
#define _I64_MAX 9223372036854775808
|
||||
#define _UI64_MAX 18446744073709551615
|
||||
|
||||
#endif /* LIMITS_H_ */
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "machine/_stdint.h"
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#define offsetof(t, m) ((size_t)(&(t *)0)->m)
|
||||
#define offsetof(t, m) ((size_t)&(((t *)0)->m))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
||||
@@ -29,13 +29,22 @@ extern FILE *stderr;
|
||||
|
||||
extern FILE *fopen(const char *path, const char *mode);
|
||||
extern FILE *freopen(const char *path, const char *mode, FILE *fp);
|
||||
#ifdef __magenta__
|
||||
extern FILE *fdopen(mx_handle_t fd, const char *mode);
|
||||
#else
|
||||
extern FILE *fdopen(int fd, const char *mode);
|
||||
#endif
|
||||
extern int fclose(FILE *fp);
|
||||
extern int fflush(FILE *fp);
|
||||
extern size_t fread(void *ptr, size_t size, size_t count, FILE *fp);
|
||||
extern size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp);
|
||||
|
||||
extern int fileno(FILE *fp);
|
||||
extern int fputs(const char *str, FILE *fp);
|
||||
extern int fputc(int c, FILE *fp);
|
||||
extern int fgetc(FILE *fp);
|
||||
|
||||
extern int ungetc(int c, FILE *fp);
|
||||
|
||||
extern int printf(const char *restrict format, ...);
|
||||
extern int fprintf(FILE *fp, const char *restrict format, ...);
|
||||
|
||||
@@ -12,6 +12,11 @@ extern _Noreturn void exit(int code);
|
||||
extern void *malloc(size_t sz);
|
||||
extern void free(void *ptr);
|
||||
|
||||
extern int atoi(const char *str);
|
||||
extern double atof(const char *str);
|
||||
extern long int strtol(const char *str, char **endptr, int base);
|
||||
extern double strtod(const char *str, char **endptr);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,11 @@ extern size_t strlen(const char *str);
|
||||
extern int strcmp(const char *a, const char *b);
|
||||
extern int strncmp(const char *a, const char *b, size_t sz);
|
||||
|
||||
extern char *strcpy(char *dest, const char *src);
|
||||
extern char *strncpy(char *dest, const char *src, size_t sz);
|
||||
|
||||
extern char *strdup(const char *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <__fio.h>
|
||||
|
||||
#ifdef __magenta__
|
||||
FILE *fdopen(mx_handle_t fd, const char *mode)
|
||||
#else
|
||||
FILE *fdopen(int fd, const char *mode)
|
||||
#endif
|
||||
{
|
||||
struct __io_file *fp = malloc(sizeof(*fp));
|
||||
memset(fp, 0x0, sizeof(*fp));
|
||||
|
||||
int res = __fio_fdopen(fd, mode, fp);
|
||||
if (res != 0) {
|
||||
free(fp);
|
||||
|
||||
13
photon/libc/stdio/fgetc.c
Normal file
13
photon/libc/stdio/fgetc.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <__fio.h>
|
||||
|
||||
int fgetc(FILE *fp)
|
||||
{
|
||||
char ch = 0;
|
||||
__fio_read(fp, &ch, 1);
|
||||
if (__fio_error(fp)) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <__fio.h>
|
||||
|
||||
FILE *fopen(const char *path, const char *mode)
|
||||
{
|
||||
struct __io_file *fp = malloc(sizeof(*fp));
|
||||
memset(fp, 0x0, sizeof(*fp));
|
||||
|
||||
int res = __fio_fopen(path, mode, fp);
|
||||
if (res != 0) {
|
||||
free(fp);
|
||||
|
||||
12
photon/libc/stdio/fwrite.c
Normal file
12
photon/libc/stdio/fwrite.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <__fio.h>
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp)
|
||||
{
|
||||
if (!size || !count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int written = __fio_write(fp, ptr, size * count);
|
||||
return written / size;
|
||||
}
|
||||
8
photon/libc/stdio/ungetc.c
Normal file
8
photon/libc/stdio/ungetc.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <__fio.h>
|
||||
|
||||
int ungetc(int c, FILE *fp)
|
||||
{
|
||||
int res = __fio_ungetc(fp, c);
|
||||
return res == -1 ? EOF : c;
|
||||
}
|
||||
42
photon/libc/stdlib/atof.c
Normal file
42
photon/libc/stdlib/atof.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <ctype.h>
|
||||
|
||||
double atof(const char *s)
|
||||
{
|
||||
double a = 0.0;
|
||||
int e = 0;
|
||||
int c;
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
}
|
||||
if (c == '.') {
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
e = e-1;
|
||||
}
|
||||
}
|
||||
if (c == 'e' || c == 'E') {
|
||||
int sign = 1;
|
||||
int i = 0;
|
||||
c = *s++;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
else if (c == '-') {
|
||||
c = *s++;
|
||||
sign = -1;
|
||||
}
|
||||
while (isdigit(c)) {
|
||||
i = i*10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
e += i*sign;
|
||||
}
|
||||
while (e > 0) {
|
||||
a *= 10.0;
|
||||
e--;
|
||||
}
|
||||
while (e < 0) {
|
||||
a *= 0.1;
|
||||
e++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
0
photon/libc/stdlib/atoi.c
Normal file
0
photon/libc/stdlib/atoi.c
Normal file
91
photon/libc/stdlib/strtod.c
Normal file
91
photon/libc/stdlib/strtod.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
double strtod(const char *str, char **ptr)
|
||||
{
|
||||
if (ptr == (char **)0) {
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
size_t len = strlen(str);
|
||||
char rstr[len + 1];
|
||||
strcpy(rstr, str);
|
||||
|
||||
char *p = rstr;
|
||||
|
||||
while (isspace(*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == '+' || *p == '-') {
|
||||
++p;
|
||||
}
|
||||
|
||||
if ((p[0] == 'i' || p[0] == 'I')
|
||||
&& (p[1] == 'n' || p[1] == 'N')
|
||||
&& (p[2] == 'f' || p[2] == 'F')) {
|
||||
if ((p[3] == 'i' || p[3] == 'I')
|
||||
&& (p[4] == 'n' || p[4] == 'N')
|
||||
&& (p[5] == 'i' || p[5] == 'I')
|
||||
&& (p[6] == 't' || p[6] == 'T')
|
||||
&& (p[7] == 'y' || p[7] == 'Y')) {
|
||||
*ptr = p + 8;
|
||||
return atof(str);
|
||||
} else {
|
||||
*ptr = p + 3;
|
||||
return atof(str);
|
||||
}
|
||||
}
|
||||
|
||||
if ((p[0] == 'n' || p[0] == 'N')
|
||||
&& (p[1] == 'a' || p[1] == 'A')
|
||||
&& (p[2] == 'n' || p[2] == 'N')) {
|
||||
p += 3;
|
||||
if (*p == '(') {
|
||||
++p;
|
||||
while (*p != '\0' && *p != ')') {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == ')') {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = p;
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
if (isdigit(*p) || *p == '.') {
|
||||
int got_dot = 0;
|
||||
while (isdigit(*p) || (!got_dot && *p == '.')) {
|
||||
if (*p == '.')
|
||||
got_dot = 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == 'e' || *p == 'E') {
|
||||
int i;
|
||||
i = 1;
|
||||
if (p[i] == '+' || p[i] == '-') {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (isdigit (p[i])) {
|
||||
while (isdigit (p[i])) {
|
||||
++i;
|
||||
}
|
||||
|
||||
*ptr = p + i;
|
||||
return atof(str);
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = p;
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
*ptr = (char *)str;
|
||||
return 0.0;
|
||||
}
|
||||
85
photon/libc/stdlib/strtol.c
Normal file
85
photon/libc/stdlib/strtol.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
long strtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s = nptr;
|
||||
unsigned long acc;
|
||||
int c;
|
||||
unsigned long cutoff;
|
||||
int neg = 0, any, cutlim;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace(c));
|
||||
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
} else if ((base == 0 || base == 2) &&
|
||||
c == '0' && (*s == 'b' || *s == 'B')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 2;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % (unsigned long)base;
|
||||
cutoff /= (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
12
photon/libc/string/fread.c
Normal file
12
photon/libc/string/fread.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <__fio.h>
|
||||
|
||||
size_t fread(void *ptr, size_t size, size_t count, FILE *fp)
|
||||
{
|
||||
if (!size || !count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int written = __fio_read(fp, ptr, size * count);
|
||||
return written / size;
|
||||
}
|
||||
0
photon/libc/string/fwrite.c
Normal file
0
photon/libc/string/fwrite.c
Normal file
19
photon/libc/string/strcmp.c
Normal file
19
photon/libc/string/strcmp.c
Normal file
@@ -0,0 +1,19 @@
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; s1[i] == s2[i]; i++)
|
||||
if (s1[i] == '\0')
|
||||
return 0;
|
||||
|
||||
return s1[i] - s2[i];
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, unsigned int n)
|
||||
{
|
||||
for (; n > 0; s1++, s2++, --n)
|
||||
if (*s1 != *s2)
|
||||
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : 1);
|
||||
else if (*s1 == '\0')
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
26
photon/libc/string/strcpy.c
Normal file
26
photon/libc/string/strcpy.c
Normal file
@@ -0,0 +1,26 @@
|
||||
char *strcpy(char *output, const char *input)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; input[i] != 0; i++) {
|
||||
output[i] = input[i];
|
||||
}
|
||||
|
||||
output[i] = '\0';
|
||||
return output;
|
||||
}
|
||||
|
||||
char *strncpy(char *output, const char *input, unsigned int count)
|
||||
{
|
||||
unsigned int size = count;
|
||||
unsigned int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
output[i] = input[i];
|
||||
|
||||
if (input[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output[i] = '\0';
|
||||
return output;
|
||||
}
|
||||
11
photon/libc/string/strdup.c
Normal file
11
photon/libc/string/strdup.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *strdup(const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char *out = malloc(len + 1);
|
||||
memcpy(out, str, len);
|
||||
out[len] = 0;
|
||||
return out;
|
||||
}
|
||||
@@ -14,17 +14,20 @@ struct __io_file {
|
||||
unsigned long buf_idx;
|
||||
mx_handle_t handle;
|
||||
char err;
|
||||
char unget;
|
||||
};
|
||||
|
||||
extern int __fileno(struct __io_file *f);
|
||||
extern void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err);
|
||||
extern unsigned int __fio_read(struct __io_file *f, char *buf, unsigned int sz);
|
||||
extern unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz);
|
||||
extern unsigned int __fio_flush(struct __io_file *f);
|
||||
extern int __fio_error(struct __io_file *f);
|
||||
extern int __fio_ungetc(struct __io_file *f, char c);
|
||||
|
||||
extern int __fio_fopen(const char *path, const char *mode, struct __io_file *out);
|
||||
extern int __fio_fclose(struct __io_file *in);
|
||||
extern int __fio_fdopen(int fd, const char *mode, struct __io_file *out);
|
||||
extern int __fio_fdopen(mx_handle_t fd, const char *mode, struct __io_file *out);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,38 @@ struct __io_file *stdin = &__stdin;
|
||||
struct __io_file *stdout = &__stdout;
|
||||
struct __io_file *stderr = &__stderr;
|
||||
|
||||
static mx_flags_t flags_from_mode(const char *r)
|
||||
{
|
||||
mx_flags_t out = 0;
|
||||
|
||||
while (*r) {
|
||||
switch (*r) {
|
||||
case 'r':
|
||||
out |= MX_FILE_READ;
|
||||
break;
|
||||
case 'w':
|
||||
out |= MX_FILE_WRITE;
|
||||
break;
|
||||
case '+':
|
||||
out |= (MX_FILE_READ | MX_FILE_WRITE);
|
||||
break;
|
||||
case 'a':
|
||||
out |= MX_FILE_APPEND;
|
||||
break;
|
||||
case 'b':
|
||||
/* TODO */
|
||||
break;
|
||||
default:
|
||||
out = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
r++;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err)
|
||||
{
|
||||
__stdin.handle = in;
|
||||
@@ -16,11 +48,59 @@ void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err)
|
||||
__stderr.handle = err;
|
||||
}
|
||||
|
||||
int __fio_fopen(const char *path, const char *mode, struct __io_file *fp)
|
||||
{
|
||||
mx_handle_t h = MX_NULL_HANDLE;
|
||||
mx_status_t stat = mx_open(MX_NULL_HANDLE, path, 0, &h);
|
||||
|
||||
if (stat != MX_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fp->handle = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __fio_fdopen(mx_handle_t fd, const char *mode, struct __io_file *fp)
|
||||
{
|
||||
/* TODO validate handle and mode */
|
||||
fp->handle = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __fileno(struct __io_file *f)
|
||||
{
|
||||
return (int)f->handle;
|
||||
}
|
||||
|
||||
unsigned int __fio_read(struct __io_file *f, char *buf, unsigned int sz)
|
||||
{
|
||||
if (!sz) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
unsigned long real_sz = 0;
|
||||
|
||||
if (f->unget) {
|
||||
buf[i++] = f->unget;
|
||||
f->unget = 0;
|
||||
sz--;
|
||||
}
|
||||
|
||||
if (!sz) {
|
||||
return real_sz;
|
||||
}
|
||||
|
||||
mx_status_t err = mx_read(f->handle, sz, buf + i, &real_sz);
|
||||
|
||||
if (err != MX_OK || real_sz != sz) {
|
||||
f->err = 1;
|
||||
}
|
||||
|
||||
return real_sz + i;
|
||||
}
|
||||
|
||||
unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz)
|
||||
{
|
||||
for (unsigned int i = 0; i < sz; i++) {
|
||||
@@ -37,6 +117,16 @@ unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz)
|
||||
return sz;
|
||||
}
|
||||
|
||||
int __fio_ungetc(struct __io_file *f, char c)
|
||||
{
|
||||
if (f->unget) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
f->unget = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int __fio_flush(struct __io_file *f)
|
||||
{
|
||||
unsigned long written = 0;
|
||||
|
||||
Reference in New Issue
Block a user