stdio fgets and stuff that actually kinda work correctly
This commit is contained in:
parent
5cf95b4fc0
commit
a3b1b253d7
@ -37,82 +37,10 @@ void parse_url(char * d, struct uri * r) {
|
||||
}
|
||||
}
|
||||
|
||||
static char read_buf[1024];
|
||||
static size_t available = 0;
|
||||
static size_t offset = 0;
|
||||
static size_t read_from = 0;
|
||||
static char * read_line(FILE * f, char * out, ssize_t len) {
|
||||
while (len > 0) {
|
||||
if (available == 0) {
|
||||
if (offset == 1024) {
|
||||
offset = 0;
|
||||
}
|
||||
size_t r = read(fileno(f), &read_buf[offset], 1024 - offset);
|
||||
read_from = offset;
|
||||
available = r;
|
||||
offset += available;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Available: %d\n", available);
|
||||
fprintf(stderr, "Remaining length: %d\n", len);
|
||||
fprintf(stderr, "Read from: %d\n", read_from);
|
||||
fprintf(stderr, "Offset: %d\n", offset);
|
||||
#endif
|
||||
|
||||
if (available == 0) {
|
||||
return out;
|
||||
}
|
||||
|
||||
while (read_from < offset && len > 0) {
|
||||
*out = read_buf[read_from];
|
||||
len--;
|
||||
read_from++;
|
||||
available--;
|
||||
if (*out == '\n') {
|
||||
return out;
|
||||
}
|
||||
out++;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
static size_t read_bytes(FILE * f, char * out, ssize_t len) {
|
||||
size_t r_out = 0;
|
||||
while (len > 0) {
|
||||
if (available == 0) {
|
||||
if (offset == 1024) {
|
||||
offset = 0;
|
||||
}
|
||||
size_t r = read(fileno(f), &read_buf[offset], 1024 - offset);
|
||||
read_from = offset;
|
||||
available = r;
|
||||
offset += available;
|
||||
}
|
||||
|
||||
if (available == 0) {
|
||||
return r_out;
|
||||
}
|
||||
|
||||
while (read_from < offset && len > 0) {
|
||||
*out = read_buf[read_from];
|
||||
len--;
|
||||
read_from++;
|
||||
available--;
|
||||
out++;
|
||||
r_out += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return r_out;
|
||||
}
|
||||
|
||||
|
||||
void read_http_line(char * buf, FILE * f) {
|
||||
memset(buf, 0x00, 256);
|
||||
|
||||
read_line(f, buf, 255);
|
||||
fgets(buf, 255, f);
|
||||
char * _r = strchr(buf, '\r');
|
||||
if (_r) {
|
||||
*_r = '\0';
|
||||
@ -223,7 +151,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
while (bytes_to_read > 0) {
|
||||
char buf[1024];
|
||||
size_t r = read_bytes(f, buf, bytes_to_read < 1024 ? bytes_to_read : 1024);
|
||||
size_t r = fread(buf, 1, bytes_to_read < 1024 ? bytes_to_read : 1024, f);
|
||||
fwrite(buf, 1, r, stdout);
|
||||
bytes_to_read -= r;
|
||||
}
|
||||
|
44
apps/panel.c
44
apps/panel.c
@ -266,48 +266,6 @@ static void volume_lower(void) {
|
||||
redraw();
|
||||
}
|
||||
|
||||
static char read_buf[1024];
|
||||
static size_t available = 0;
|
||||
static size_t offset = 0;
|
||||
static size_t read_from = 0;
|
||||
static char * read_line(FILE * f, char * out, ssize_t len) {
|
||||
while (len > 0) {
|
||||
if (available == 0) {
|
||||
if (offset == 1024) {
|
||||
offset = 0;
|
||||
}
|
||||
size_t r = read(fileno(f), &read_buf[offset], 1024 - offset);
|
||||
read_from = offset;
|
||||
available = r;
|
||||
offset += available;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Available: %d\n", available);
|
||||
fprintf(stderr, "Remaining length: %d\n", len);
|
||||
fprintf(stderr, "Read from: %d\n", read_from);
|
||||
fprintf(stderr, "Offset: %d\n", offset);
|
||||
#endif
|
||||
|
||||
if (available == 0) {
|
||||
*out = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
while (read_from < offset && len > 0) {
|
||||
*out = read_buf[read_from];
|
||||
len--;
|
||||
read_from++;
|
||||
available--;
|
||||
if (*out == '\n') {
|
||||
return out;
|
||||
}
|
||||
out++;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
static void update_network_status(void) {
|
||||
FILE * net = fopen("/proc/netif","r");
|
||||
|
||||
@ -315,7 +273,7 @@ static void update_network_status(void) {
|
||||
|
||||
do {
|
||||
memset(line, 0, 256);
|
||||
read_line(net, line, 256);
|
||||
fgets(line, 256, net);
|
||||
if (!*line) break;
|
||||
if (strstr(line,"no network") != NULL) {
|
||||
network_status = 0;
|
||||
|
@ -3,9 +3,9 @@
|
||||
#include <stddef.h>
|
||||
#include <va_list.h>
|
||||
|
||||
typedef struct _FILE {
|
||||
int fd;
|
||||
} FILE;
|
||||
typedef struct _FILE FILE;
|
||||
|
||||
#define BUFSIZ 1024
|
||||
|
||||
extern FILE * stdin;
|
||||
extern FILE * stdout;
|
||||
@ -44,3 +44,5 @@ extern void rewind(FILE *stream);
|
||||
extern void setbuf(FILE * stream, char * buf);
|
||||
|
||||
extern void perror(const char *s);
|
||||
|
||||
extern int ungetc(int c, FILE * stream);
|
||||
|
@ -55,6 +55,9 @@ extern void _fini();
|
||||
char ** environ;
|
||||
int _environ_size = 0;
|
||||
|
||||
|
||||
extern void __stdio_init_buffers(void);
|
||||
|
||||
void _exit(int val){
|
||||
_fini();
|
||||
syscall_exit(val);
|
||||
@ -62,6 +65,8 @@ void _exit(int val){
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
char * _argv_0 = NULL;
|
||||
|
||||
void pre_main(int (*main)(int,char**), int argc, char * argv[]) {
|
||||
unsigned int x = 0;
|
||||
unsigned int nulls = 0;
|
||||
@ -78,6 +83,8 @@ void pre_main(int (*main)(int,char**), int argc, char * argv[]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_argv_0 = argv[0];
|
||||
__stdio_init_buffers();
|
||||
_init();
|
||||
_exit(main(argc, argv));
|
||||
}
|
||||
|
@ -1,25 +1,124 @@
|
||||
#include <stdio.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <_xlog.h>
|
||||
|
||||
struct _FILE {
|
||||
int fd;
|
||||
|
||||
char * read_buf;
|
||||
int available;
|
||||
int offset;
|
||||
int read_from;
|
||||
int ungetc;
|
||||
};
|
||||
|
||||
FILE _stdin = {
|
||||
.fd = 0,
|
||||
.read_buf = NULL,
|
||||
.available = 0,
|
||||
.offset = 0,
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
};
|
||||
|
||||
FILE _stdout = {
|
||||
.fd = 1,
|
||||
.read_buf = NULL,
|
||||
.available = 0,
|
||||
.offset = 0,
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
};
|
||||
|
||||
FILE _stderr = {
|
||||
.fd = 2,
|
||||
.read_buf = NULL,
|
||||
.available = 0,
|
||||
.offset = 0,
|
||||
.read_from = 0,
|
||||
.ungetc = -1,
|
||||
};
|
||||
|
||||
FILE * stdin = &_stdin;
|
||||
FILE * stdout = &_stdout;
|
||||
FILE * stderr = &_stderr;
|
||||
|
||||
void __stdio_init_buffers(void) {
|
||||
_stdin.read_buf = malloc(BUFSIZ);
|
||||
//_stdout.read_buf = malloc(BUFSIZ);
|
||||
//_stderr.read_buf = malloc(BUFSIZ);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char * stream_id(FILE * stream) {
|
||||
static char out[] = "stream\0\0\0\0\0\0";
|
||||
if (stream == &_stdin) return "stdin";
|
||||
if (stream == &_stdout) return "stdout";
|
||||
if (stream == &_stderr) return "stderr";
|
||||
sprintf(out, "stream %d", fileno(stream));
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern char * _argv_0;
|
||||
|
||||
|
||||
static size_t read_bytes(FILE * f, char * out, size_t len) {
|
||||
size_t r_out = 0;
|
||||
|
||||
//fprintf(stderr, "%s: Read %d bytes from %s\n", _argv_0, len, stream_id(f));
|
||||
//fprintf(stderr, "%s: off[%d] avail[%d] read[%d]\n", _argv_0, f->offset, f->available, f->read_from);
|
||||
|
||||
while (len > 0) {
|
||||
if (f->ungetc >= 0) {
|
||||
*out = f->ungetc;
|
||||
len--;
|
||||
out++;
|
||||
r_out++;
|
||||
f->ungetc = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f->available == 0) {
|
||||
if (f->offset == BUFSIZ) {
|
||||
f->offset = 0;
|
||||
}
|
||||
ssize_t r = read(fileno(f), &f->read_buf[f->offset], BUFSIZ - f->offset);
|
||||
if (r < 0) {
|
||||
//fprintf(stderr, "error condition\n");
|
||||
return r_out;
|
||||
} else {
|
||||
f->read_from = f->offset;
|
||||
f->available = r;
|
||||
f->offset += f->available;
|
||||
}
|
||||
}
|
||||
|
||||
if (f->available == 0) {
|
||||
/* EOF condition */
|
||||
//fprintf(stderr, "%s: no bytes available, returning read value of %d\n", _argv_0, r_out);
|
||||
return r_out;
|
||||
}
|
||||
|
||||
//fprintf(stderr, "%s: reading until %d reaches %d or %d reaches 0\n", _argv_0, f->read_from, f->offset, len);
|
||||
while (f->read_from < f->offset && len > 0) {
|
||||
*out = f->read_buf[f->read_from];
|
||||
len--;
|
||||
f->read_from++;
|
||||
f->available--;
|
||||
out++;
|
||||
r_out += 1;
|
||||
}
|
||||
}
|
||||
|
||||
//fprintf(stderr, "%s: read completed, returning read value of %d\n", _argv_0, r_out);
|
||||
return r_out;
|
||||
}
|
||||
|
||||
FILE * fopen(const char *path, const char *mode) {
|
||||
|
||||
const char * x = mode;
|
||||
@ -54,22 +153,52 @@ FILE * fopen(const char *path, const char *mode) {
|
||||
|
||||
FILE * out = malloc(sizeof(FILE));
|
||||
out->fd = fd;
|
||||
out->read_buf = malloc(BUFSIZ);
|
||||
out->available = 0;
|
||||
out->read_from = 0;
|
||||
out->offset = 0;
|
||||
out->ungetc = -1;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int ungetc(int c, FILE * stream) {
|
||||
if (stream->ungetc > 0)
|
||||
return EOF;
|
||||
|
||||
return (stream->ungetc = c);
|
||||
}
|
||||
|
||||
FILE * fdopen(int fd, const char *mode){
|
||||
FILE * out = malloc(sizeof(FILE));
|
||||
out->fd = fd;
|
||||
out->read_buf = malloc(BUFSIZ);
|
||||
out->available = 0;
|
||||
out->read_from = 0;
|
||||
out->offset = 0;
|
||||
out->ungetc = -1;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int fclose(FILE * stream) {
|
||||
return syscall_close(stream->fd);
|
||||
int out = syscall_close(stream->fd);
|
||||
free(stream->read_buf);
|
||||
if (stream == &_stdin || stream == &_stdout || stream == &_stderr) {
|
||||
return out;
|
||||
} else {
|
||||
free(stream);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
int fseek(FILE * stream, long offset, int whence) {
|
||||
//fprintf(stderr, "%s: seek called, resetting\n", _argv_0);
|
||||
stream->offset = 0;
|
||||
stream->read_from = 0;
|
||||
stream->available = 0;
|
||||
stream->ungetc = -1;
|
||||
|
||||
int resp = syscall_lseek(stream->fd,offset,whence);
|
||||
if (resp < 0) {
|
||||
return -1;
|
||||
@ -78,14 +207,18 @@ int fseek(FILE * stream, long offset, int whence) {
|
||||
}
|
||||
|
||||
long ftell(FILE * stream) {
|
||||
//fprintf(stderr, "%s: tell called, resetting\n", _argv_0);
|
||||
stream->offset = 0;
|
||||
stream->read_from = 0;
|
||||
stream->available = 0;
|
||||
stream->ungetc = -1;
|
||||
return syscall_lseek(stream->fd, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream) {
|
||||
char * tracking = (char*)ptr;
|
||||
for (size_t i = 0; i < nmemb; ++i) {
|
||||
int r = syscall_read(stream->fd, tracking, size);
|
||||
int r = read_bytes(stream, tracking, size);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -145,19 +278,16 @@ int fgetc(FILE * stream) {
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
return fputc(c, stdout);
|
||||
}
|
||||
|
||||
void rewind(FILE *stream) {
|
||||
fseek(stream, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
char *fgets(char *s, int size, FILE *stream) {
|
||||
int c;
|
||||
char * out = s;
|
||||
while ((c = fgetc(stream)) > 0) {
|
||||
*s++ = c;
|
||||
size--;
|
||||
if (size == 0) {
|
||||
return out;
|
||||
}
|
||||
*s = '\0';
|
||||
if (c == '\n') {
|
||||
return out;
|
||||
}
|
||||
@ -172,6 +302,14 @@ char *fgets(char *s, int size, FILE *stream) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
return fputc(c, stdout);
|
||||
}
|
||||
|
||||
void rewind(FILE *stream) {
|
||||
fseek(stream, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
void setbuf(FILE * stream, char * buf) {
|
||||
// ...
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user