diff --git a/lib/libio.c b/lib/libio.c index 9b2291f..4cdeea6 100644 --- a/lib/libio.c +++ b/lib/libio.c @@ -1,7 +1,24 @@ #include +#include #include #include "libio.h" +/* Backups of standard library systems for the odd scenario where there is no + * standard library but there is the write(2) system call. */ +static int _isdigit(int c); +static int _strlen(char *s); + +/* Wrappers around write(2) */ +static int _write(int fd, char *s, int n); +static int _write1(int fd, int c); + +/* Normally in */ +static int +_isdigit(int c){ + return c >= '0' && c <= '9'; +} + +/* Normally in */ static int _strlen(char *s){ int i; @@ -11,6 +28,8 @@ _strlen(char *s){ return i; } +/* Wrapper around write(2) - keeps re-running write(2) until the operation + * succeeds in full. Usually unnecessary but still good. */ static int _write(int fd, char *s, int n){ int i; @@ -24,32 +43,40 @@ _write(int fd, char *s, int n){ return i; } -int -fdprint(int fd, char *s){ - return _write(fd, s, _strlen(s)); -} - -/* SLOW. DO NOT USE. */ -static int write1(int fd, int c){ +/* For writing a single character. To optimize for speed, functions should + * allocate a buffer and add to that buffer before write(2)ing the buffer out + * in a single system call. However sometimes cheap tricks are as effective. */ +static int +_write1(int fd, int c){ while(write(fd, &c, 1) != 1); return 1; } -int fdputd(int fd, int d){ +int +fdprint(int fd, char *s){ + return _write(fd, s, strlen(s)); +} + +int +fdputd(int fd, int d){ int r; int s; r = 0; /* Just an implementation looking for a math person to improve it... */ + /* Rather than storing the log base 10 of d, store 10^(log base 10 (d)) + * which requires less Weird Hax. Then slowly chop off digits and print + * out the system encoding's representations. Finally, print a newline. + * Generally this function is slow and sucks implementation-wise. */ if(d < 100){ s = d < 10 ? 1 : 10; goto put; } for(s = 10; d > (s *= 10);); put: while(s > 0){ - r += write1(1, (d - (d % s)) / s + '0'); + r += _write1(fd, (d - (d % s)) / s + '0'); if((s /= 10) == 0) - r += write1(1, '\n'); + r += _write1(fd, '\n'); } return r; @@ -60,7 +87,7 @@ fdputs(int fd, char *s){ int i; int r; - i = _strlen(s); + i = strlen(s); /* RACE CONDITION */ /* This leaves s as an invalid string while the write(2) syscall is diff --git a/src/echo.c b/src/echo.c index adf1e94..a1fab77 100644 --- a/src/echo.c +++ b/src/echo.c @@ -1,16 +1,15 @@ #include #include /* NULL */ #include /* write(2) */ +#include "libio.h" /* fdprint(3) */ int main(int argc, char **argv){ - int s; if(*argv == NULL) return EX_OSERR; while(*++argv != NULL){ - for(s = 0; *(*argv+s) != '\0'; ++s); - write(1, *argv, s); + fdprint(1, *argv); if(*(argv+1) != NULL) write(1, " ", 1);