fdputd(3)
This commit is contained in:
parent
6cd5be5141
commit
1cb1e48415
78
lib/libio.c
78
lib/libio.c
@ -1,30 +1,72 @@
|
||||
#ifndef _LIBIO_H
|
||||
#include <unistd.h>
|
||||
|
||||
# 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 */
|
||||
|
6
lib/libio.h
Normal file
6
lib/libio.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user