Update TODO. Update Makefile. Add sleep. Add wc.

This commit is contained in:
Mid Favila 2022-10-01 14:38:29 -04:00
parent b7ac76440a
commit d8bb1fcc3e
5 changed files with 284 additions and 96 deletions

194
TODO
View File

@ -1,90 +1,108 @@
Write a Makefile.
Write a Makefile. [done]
Add octal escape support to echo.
Rework yes(1) to buffer input. This achieves greater throughput per system call.
Rework yes(1) to buffer output. This achieves greater throughput per system call.
Write the following utilities:
ar
at/atd
basename
batch(?)
bc
cal
cat (done)
chgrp
chmod
chown
cksum
cmp
comm
compress(?)
cp
crond/crontab
csplit
cut
dd
df
diff
dirname
du
ed/x
expand(?)
expr
file
find
fold
fuser
grep
head
iconv
id
join
kill
link(?)
ln
locale
localedef
logname
lp(?)
ls
mesg
mkdir
mkfifo
mknod
mktemp
more
mv
newgrp(?)
nice
nl
paste
pathchk(?)
pax
printf
ps
pwd
renice
rm
rmdir
sed
sh
sleep
sort
split
strings
tabs
tail
talk(?)
tee
test
touch
tput
tr
tsort
uname
uncompress(?)
unexpand
uniq
wc [in progress]
who
write(?)
xargs
-----------------------------------------------------
PROGS
_____________________________________________________
Simple commands (only a handful of parameters at most, with simple premises)
-sleep [done]
-true [done]
-yes [done]
-basename/dirname
-echo [in-progress, SUS]
-wc [in-progress]
-tee
-cat [done]
-pwd
-cksum
-cal
Filesystem modifiers
-rm
-mv
-cp
-mkdir
-rmdir
-mktemp
-chgrp
-chown
-chmod
-mkfifo
-mknod
-touch
-ln
-link(?)
-ls
-find
-file
Filters
-sed
-nl
-tr
-expand/unexpand
-fold
-head/tail
-sort
-grep
-uniq
-cut
-paste
-csplit
-iconv
Sorting, searching and testing
-test
-cmp
-comm
-diff
-tsort
-du
-df
-join
-split
System interfaces
-uname
-tput
-who
-ps
-kill
-renice
-nice
-newgrp
-pathchk
-fuser
-id
-tabs
-lp
-locale
-localedef
-at/atd
-batch
-crond
-crontab
-logname
Binary utilities
-ar
-tar
-pax
-od
-dd
-compress
-expand
-strings
Interactive utilities
-ed
-bc
-sh
Miscellaneous
-xargs
-mesg [maybe]
-write [maybe]
-printf
-expr

View File

@ -6,16 +6,18 @@ LDFLAGS = -static
LDLIBS =
PREFIX = usr/local
DESTDIR =
BIN = echo yes true false cat
BIN = cat\
false\
sleep\
true\
yes\
echo\
wc\
all: ${BIN}
echo: echo.c
wc: wc.c
yes: yes.c
true: true.c
false:
false: true
ln -s true false
cat: cat.c
install: all
install -Dm0755 ${BIN} ${DESTDIR}/${PREFIX}/bin

36
src/sleep.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include "support.h"
int main(int argc, char **argv)
{
int i;
i = 0;
if(argc != 2)
{
throw(NEEDARG_FAIL, mastrcat(argv[0], " int"));
}
i = (int) (strtol(argv[1], (char **) NULL, 10));
if(errno == ERANGE)
{
throw(TIME_FAIL, mastrcat(argv[0], " ERANGE error."));
}
if(i < 0)
{
throw(MISC_FAIL, mastrcat(argv[0], ": need positive number."));
}
sleep(i);
exit(0);
}

View File

@ -11,7 +11,9 @@ enum {
MALLOC_FAIL,
NEEDARG_FAIL,
FOPEN_FAIL,
WRITE_FAIL
WRITE_FAIL,
TIME_FAIL,
MISC_FAIL
};
@ -54,6 +56,10 @@ void throw(long unsigned int condition, void *info)
exit(FOPEN_FAIL);
case WRITE_FAIL: printf("failed to write: %s\n", (char *) info);
exit(WRITE_FAIL);
case TIME_FAIL: printf("time error: %s\n", (char *) info);
exit(TIME_FAIL);
case MISC_FAIL: printf("%s\n", (char *) info);
exit(MISC_FAIL);
default: printf("You shouldn't be seeing this.\nSomething is very wrong.\n");
exit(-256);
}

126
src/wc.c Normal file
View File

@ -0,0 +1,126 @@
/* wc.c -- program to count and display the number of lines, words and one of bytes or characters in the named files */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include "support.h"
enum
{
C,
M,
L,
W,
OUTWORD,
INWORD,
/* character or byte */
COB = 0,
WORDS = 1,
LINES = 2,
};
int main(int argc, char **argv)
{
char state;
int c, i;
char par[4] = {1};
/* M and C conflict; M counts actual characters (theoretically), so we should go with that as the default */
par[C] = 0;
int count[3] = {0};
int total[3] = {0};
FILE *fd;
state = OUTWORD;
c = i = 0;
fd = 0;
/* process our parameters */
for(; (c = getopt(argc, argv, "cmlw")) != -1; c = 0)
{
switch(c)
{
case 'c': par[C] = 1;
par[M] = 0;
break;
case 'm': par[M] = 1;
par[C] = 0;
break;
case 'l': par[L] = 1;
break;
case 'w': par[W] = 1;
break;
/* Fall-through to default from ':' */
case ':':
case '?':
default: throw(NEEDARG_FAIL, mastrcat(argv[0], "[-c|-m] [-lw] [file ...]"));
break;
}
}
/* for every file we're given... */
for(fd = 0, i = optind; i < argc; fclose(fd), i++)
{
/* ...open our file... */
if( !(fd = fopen(argv[i], "r")))
{
printf("%d %d\n", i, optind);
exit(1);
}
/* ...then read until EOF... */
for(c = 0; (c = fgetc(fd)) != EOF;)
{
/* ...and count the goods as we go. */
if(!(isblank(c) || c == '\n'))
{
if(state == OUTWORD)
{
count[WORDS]++;
}
state = INWORD;
}
else
{
if(c == '\n')
{
count[LINES]++;
}
state = OUTWORD;
}
count[COB]++;
}
/* ...then print our total and reset. */
printf("%d %d %d %s\n", count[LINES], count[WORDS], count[COB], argv[i]);
total[COB] += count[COB];
total[WORDS] += count[WORDS];
total[LINES] += count[LINES];
count[COB] = 0;
count[WORDS] = 0;
count[LINES] = 0;
}
if((argc-optind) > 1)
{
printf("%d %d %d total\n", total[LINES], total[WORDS], total[COB]);
}
exit(0);
}