make echo better
This commit is contained in:
		
							parent
							
								
									b3bb6acce9
								
							
						
					
					
						commit
						ad8cca39ae
					
				
							
								
								
									
										49
									
								
								lib/libio.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								lib/libio.c
									
									
									
									
									
								
							@ -1,7 +1,24 @@
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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 <ctype.h> */
 | 
			
		||||
static int
 | 
			
		||||
_isdigit(int c){
 | 
			
		||||
	return c >= '0' && c <= '9';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Normally in <string.h> */
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,15 @@
 | 
			
		||||
#include <sysexits.h>
 | 
			
		||||
#include <stddef.h> /* NULL */
 | 
			
		||||
#include <unistd.h> /* 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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user