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
|
static int
|
||||||
|
_strlen(char *s){
|
||||||
int
|
|
||||||
fdputs(int fd, const char *s){
|
|
||||||
int i;
|
int i;
|
||||||
int r;
|
|
||||||
|
|
||||||
for(i = 0; s[i] != '\0'; ++i);
|
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';
|
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';
|
s[i] = '\0';
|
||||||
/* /danger */
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifndef _STDIO_H
|
/* 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;. */
|
||||||
int
|
unsigned int
|
||||||
puts(const char *s){
|
parse_uint(char *s){
|
||||||
return fdputs(1, 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