From 1cb1e48415a3efa3e5fee903dc766f59e848cdac Mon Sep 17 00:00:00 2001 From: dtb Date: Thu, 9 Jun 2022 17:37:03 -0400 Subject: [PATCH] fdputd(3) --- lib/libio.c | 78 ++++++++++++++++++++++++++++++++---------- lib/libio.h | 6 ++++ src/{stris.c => str.c} | 0 3 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 lib/libio.h rename src/{stris.c => str.c} (100%) diff --git a/lib/libio.c b/lib/libio.c index 775eb96..23e7f47 100644 --- a/lib/libio.c +++ b/lib/libio.c @@ -1,30 +1,72 @@ -#ifndef _LIBIO_H +#include -# define _LIBIO_H - -int -fdputs(int fd, const char *s){ +static int +_strlen(char *s){ int i; - int r; for(i = 0; s[i] != '\0'; ++i); - /* DANGER */ + return i; +} + +static int write1(int fd, int c){ + int *s; + s = &c; + while(write(fd, s, 1) != 1); +} + +int fdputd(int fd, int d){ + int r; + int s; + + r = 0; + /* Just an implementation looking for a math person to improve it... */ + if(d < 100){ + s = d < 10 ? 1 : 10; + goto put; + } + for(s = 10; d > (s *= 10);); +put: while(s > 0){ + r += write1(fd, (d - (d % s)) / s + '0', 1); + if((s /= 10) == 0) + r += write1(fd, "\n", 1); + } +} + +int +fdputs(int fd, char *s){ + int i; + int r; + + i = _strlen(s); + r = 0; + + /* RACE CONDITION */ + /* This leaves s as an invalid string while the write(2) syscall is + * performed, which can take a non-trivial amount of time. This + * implementation is unsuitable when s is shared between threads or + * whatever the CS term for that is. */ s[i] = '\n'; - r = write(fd, s, i + 1); + for( + r = 0; + (r += write(fd, s, i + 1)) < i + 1; + s += r, i -= r + ); s[i] = '\0'; - /* /danger */ return r; } -# ifndef _STDIO_H - -int -puts(const char *s){ - return fdputs(1, s); +/* Another possible implementation would take char **s and leave *s at the next + * non-digit. But that's less simple; just while(isdigit(*s)) ++s;. */ +unsigned int +parse_uint(char *s){ + unsigned int r; + for( + r = 0; + isdigit(*s); + r = r * 10 + *s - '0', + ++s + ); + return r; } - -# endif /* ifndef _STDIO_H */ - -#endif /* ifndef _LIBIO_H */ diff --git a/lib/libio.h b/lib/libio.h new file mode 100644 index 0000000..02bec95 --- /dev/null +++ b/lib/libio.h @@ -0,0 +1,6 @@ +#ifndef _LIBIO_H +# define _LIBIO_H +int fdputd(int fd, int d); +int fdputs(int fd, char *s); +int parse_uint(char *s); +#endif /* ifndef _LIBIO_H */ diff --git a/src/stris.c b/src/str.c similarity index 100% rename from src/stris.c rename to src/str.c