Add manpages. Rewrite echo. Rewrite cat (a few times). Update Makefile.
Add ls(1) prototype.
This commit is contained in:
parent
966113d372
commit
4f9f1fb15a
5
TODO
5
TODO
@ -14,20 +14,19 @@ Simple commands (only a handful of parameters at most, with simple premises)
|
|||||||
-yes [done]
|
-yes [done]
|
||||||
-basename/dirname
|
-basename/dirname
|
||||||
-echo [in-progress, SUS]
|
-echo [in-progress, SUS]
|
||||||
-wc [in-progress]
|
-wc [done]
|
||||||
-tee
|
-tee
|
||||||
-cat [done]
|
-cat [done]
|
||||||
-pwd
|
-pwd
|
||||||
-cksum
|
-cksum
|
||||||
-cal
|
-cal
|
||||||
|
|
||||||
Filesystem modifiers
|
Filesystem interfaces
|
||||||
-rm
|
-rm
|
||||||
-mv
|
-mv
|
||||||
-cp
|
-cp
|
||||||
-mkdir
|
-mkdir
|
||||||
-rmdir
|
-rmdir
|
||||||
-mktemp
|
|
||||||
-chgrp
|
-chgrp
|
||||||
-chown
|
-chown
|
||||||
-chmod
|
-chmod
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH cat 1 2021-11-21 mp-utils Userland
|
.TH cat 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cat \- concatenate input
|
cat \- concatenate input
|
||||||
.PP
|
.PP
|
||||||
@ -12,7 +12,7 @@ including stdin. It then concatenates (attached end to end) each bit of input,
|
|||||||
before printing it to stdout.
|
before printing it to stdout.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
This implementation of cat accepts the following arguments:
|
This implementation of cat accepts the following flags:
|
||||||
|
|
||||||
-u: Unbuffered output. Print input as soon as possible.
|
-u: Unbuffered output. Print input as soon as possible.
|
||||||
|
|
||||||
|
43
doc/echo.1
43
doc/echo.1
@ -1,4 +1,4 @@
|
|||||||
.TH echo 1 2021-11-21 mp-utils Userland
|
.TH echo 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
echo \- Print argv to stdout.
|
echo \- Print argv to stdout.
|
||||||
.PP
|
.PP
|
||||||
@ -10,10 +10,28 @@ SUS
|
|||||||
backslash escapes.
|
backslash escapes.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
Echo is a standard Unix tool that accepts input from the user and prints it to stdout while applying minimal or no formatting.
|
Echo accepts input from the user and prints it to stdout while escaping the following specified sequences.
|
||||||
|
|
||||||
|
\\a \- Print a BEL.
|
||||||
|
|
||||||
|
\\b \- Print a backspace.
|
||||||
|
|
||||||
|
\\c \- Suppress the trailing newline and ignore further input.
|
||||||
|
|
||||||
|
\\f \- Print a form-feed.
|
||||||
|
|
||||||
|
\\n \- Print a newline.
|
||||||
|
|
||||||
|
\\r \- Print a carriage return.
|
||||||
|
|
||||||
|
\\t \- Print a tabulation.
|
||||||
|
|
||||||
|
\\v \- Print a vertical tabulation.
|
||||||
|
|
||||||
|
\\0 \- Print the specified codepoint (specified in octal) in the system's encoding.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
This implementation of echo accepts no arguments.
|
This implementation of echo accepts no parameters.
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
This implementation of echo requires a C89 compiler.
|
This implementation of echo requires a C89 compiler.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
@ -28,24 +46,7 @@ SUS
|
|||||||
3
|
3
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
.PP
|
.PP
|
||||||
Including the following backslash-escapes modifies echo's behavior.
|
For historical reasons implementations of echo vary wildly in their behavior across systems. For a portable way to print to stdout, see printf.
|
||||||
|
|
||||||
\\a \- Print a BEL.
|
|
||||||
|
|
||||||
\\b \- Print a backspace.
|
|
||||||
|
|
||||||
\\f \- Print a form-feed.
|
|
||||||
|
|
||||||
\\f \- Print a newline.
|
|
||||||
|
|
||||||
\\r \- Print a carriage return.
|
|
||||||
|
|
||||||
\\t \- Print a tabulation.
|
|
||||||
|
|
||||||
\\v \- Print a vertical tabulation.
|
|
||||||
|
|
||||||
\\c \- Suppress the trailing newline and ignore further input.
|
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.PP
|
.PP
|
||||||
Currently, \\0xxx (octal) escapes have not been implemented.
|
Currently, \\0xxx (octal) escapes have not been implemented.
|
||||||
|
34
doc/false.1
Normal file
34
doc/false.1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.TH false 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
false \- return EXIT_FAILURE
|
||||||
|
.PP
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.PP
|
||||||
|
Immediately exits with EXIT_FAILURE.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
false immediately returns EXIT_FAILURE.
|
||||||
|
.SH OPTIONS
|
||||||
|
.PP
|
||||||
|
This implementation of false accepts no flags.
|
||||||
|
.SH ENVIRONMENT
|
||||||
|
This implementation of false requires a C89 compiler.
|
||||||
|
.SH FILES
|
||||||
|
/usr/src/mp-utils/src/true.c
|
||||||
|
.SH CONFORMING TO
|
||||||
|
.PP
|
||||||
|
.SM
|
||||||
|
POSIX
|
||||||
|
2017,
|
||||||
|
.SM
|
||||||
|
SUS
|
||||||
|
3
|
||||||
|
.SH NOTES
|
||||||
|
.PP
|
||||||
|
None.
|
||||||
|
.SH BUGS
|
||||||
|
.PP
|
||||||
|
None known.
|
||||||
|
.SH SEE ALSO
|
||||||
|
true(1p), false(1p), true(1)
|
34
doc/sleep.1
Normal file
34
doc/sleep.1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.TH sleep 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
sleep \- wait N seconds
|
||||||
|
.PP
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.PP
|
||||||
|
Stall for N seconds before exiting.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
Sleep accepts one argument, a non-negative integer, stalls for that number of seconds, and then exits with EXIT_SUCCESS.
|
||||||
|
.SH OPTIONS
|
||||||
|
.PP
|
||||||
|
This implementation of sleep accepts no parameters.
|
||||||
|
.SH ENVIRONMENT
|
||||||
|
This implementation of sleep requires a C89 compiler.
|
||||||
|
.SH FILES
|
||||||
|
/usr/src/mp-utils/src/sleep.c
|
||||||
|
.SH CONFORMING TO
|
||||||
|
.PP
|
||||||
|
.SM
|
||||||
|
POSIX
|
||||||
|
2017,
|
||||||
|
.SM
|
||||||
|
SUS
|
||||||
|
3
|
||||||
|
.SH NOTES
|
||||||
|
.PP
|
||||||
|
None.
|
||||||
|
.SH BUGS
|
||||||
|
.PP
|
||||||
|
None known.
|
||||||
|
.SH SEE ALSO
|
||||||
|
sleep(1p)
|
34
doc/template
34
doc/template
@ -1,34 +0,0 @@
|
|||||||
.TH wc 1 2021-11-21 mp-utils Userland
|
|
||||||
|
|
||||||
.SH NAME
|
|
||||||
wc \- print to stdout forever
|
|
||||||
.PP
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.PP
|
|
||||||
Print the provided string to stdout forever.
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
Yes is a standard Unix tool that accepts input from the user and prints it to stdout repeatedly, or y when no input is provided.
|
|
||||||
.SH OPTIONS
|
|
||||||
.PP
|
|
||||||
This implementation of wc accepts no arguments.
|
|
||||||
.SH ENVIRONMENT
|
|
||||||
This implementation of wc requires a C89 compiler.
|
|
||||||
.SH FILES
|
|
||||||
/usr/src/mp-utils/src/wc.c
|
|
||||||
.SH CONFORMING TO
|
|
||||||
.PP
|
|
||||||
.SM
|
|
||||||
POSIX
|
|
||||||
2017,
|
|
||||||
.SM
|
|
||||||
SUS
|
|
||||||
3
|
|
||||||
.SH NOTES
|
|
||||||
.PP
|
|
||||||
None.
|
|
||||||
.SH BUGS
|
|
||||||
.PP
|
|
||||||
None known.
|
|
||||||
.SH SEE ALSO
|
|
||||||
wc(1p)
|
|
34
doc/true.1
Normal file
34
doc/true.1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.TH true 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
true \- return EXIT_SUCCESS
|
||||||
|
.PP
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.PP
|
||||||
|
Immediately exits with EXIT_SUCCESS.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
true immediately returns EXIT_SUCCESS.
|
||||||
|
.SH OPTIONS
|
||||||
|
.PP
|
||||||
|
This implementation of true accepts no parameters.
|
||||||
|
.SH ENVIRONMENT
|
||||||
|
This implementation of true requires a C89 compiler.
|
||||||
|
.SH FILES
|
||||||
|
/usr/src/mp-utils/src/true.c
|
||||||
|
.SH CONFORMING TO
|
||||||
|
.PP
|
||||||
|
.SM
|
||||||
|
POSIX
|
||||||
|
2017,
|
||||||
|
.SM
|
||||||
|
SUS
|
||||||
|
3
|
||||||
|
.SH NOTES
|
||||||
|
.PP
|
||||||
|
None.
|
||||||
|
.SH BUGS
|
||||||
|
.PP
|
||||||
|
None known.
|
||||||
|
.SH SEE ALSO
|
||||||
|
true(1p), false(1p), false(1)
|
4
doc/wc.1
4
doc/wc.1
@ -1,4 +1,4 @@
|
|||||||
.TH wc 1 2021-11-21 mp-utils Userland
|
.TH wc 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
wc \- count words, lines, bytes/characters
|
wc \- count words, lines, bytes/characters
|
||||||
.PP
|
.PP
|
||||||
@ -14,7 +14,7 @@ Characters in the context of wc includes multi-byte character support; that
|
|||||||
bytes are called characters is an unfortunate notational happenstance.
|
bytes are called characters is an unfortunate notational happenstance.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
This implementation of wc accepts the following arguments:
|
This implementation of wc accepts the following flags:
|
||||||
|
|
||||||
.SM
|
.SM
|
||||||
-c: Print the number of bytes.
|
-c: Print the number of bytes.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH yes 1 2021-11-21 mp-utils Userland
|
.TH yes 1 2021-11-21 mp-utils "General Commands Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
yes \- print to stdout forever
|
yes \- print to stdout forever
|
||||||
.PP
|
.PP
|
||||||
@ -10,7 +10,7 @@ Print the provided string to stdout forever.
|
|||||||
yes is a standard Unix tool that accepts input from the user and prints it to stdout repeatedly, or y when no input is provided.
|
yes is a standard Unix tool that accepts input from the user and prints it to stdout repeatedly, or y when no input is provided.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
This implementation of yes accepts no arguments.
|
This implementation of yes accepts no flags.
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
This implementation of yes requires a C89 compiler.
|
This implementation of yes requires a C89 compiler.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
72
old/cat2.c
Normal file
72
old/cat2.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* cat.c -- program to concatenate named files and/or stdin onto stdout */
|
||||||
|
/* version 2 */
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "support.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* parameters */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
U
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, c, bufsize, newbufsize;
|
||||||
|
|
||||||
|
char *buf, *newbuf;
|
||||||
|
char pars[1] = {0};
|
||||||
|
|
||||||
|
FILE *fd;
|
||||||
|
|
||||||
|
i = c = bufsize = newbufsize = 0;
|
||||||
|
|
||||||
|
buf = newbuf = 0;
|
||||||
|
|
||||||
|
fd = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* i < argc is obvious; steps through all provided args. */
|
||||||
|
/* !argc-optind && !c is a little less so - it allows this loop to run once if the user provides no paths */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if( !(fd = file_open(argv[i], "r")))
|
||||||
|
{
|
||||||
|
throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pars[U])
|
||||||
|
{
|
||||||
|
for(; (c = fgetc(fd)) != EOF; c = 0)
|
||||||
|
{
|
||||||
|
fputc(c, stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newbuf = file_read(fd, &newbufsize);
|
||||||
|
buf = concat(buf, newbuf, bufsize, newbufsize);
|
||||||
|
bufsize += newbufsize;
|
||||||
|
free(newbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++, newbufsize = 0;
|
||||||
|
}
|
||||||
|
while((i < argc) || (((argc - optind) == 0) && !c));
|
||||||
|
|
||||||
|
if(!pars[U])
|
||||||
|
{
|
||||||
|
fwrite(buf, sizeof(char), bufsize, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
71
old/echo.c
Normal file
71
old/echo.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* echo -- version one */
|
||||||
|
/* program to print its argument vector to stdout */
|
||||||
|
/* mostly SUS compliant */
|
||||||
|
|
||||||
|
|
||||||
|
#include "support.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, i2;
|
||||||
|
char escape = 0;
|
||||||
|
|
||||||
|
if(argc > 1)
|
||||||
|
for(i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
for(i2 = 0; argv[i][i2] != '\0'; i2++)
|
||||||
|
{
|
||||||
|
if(escape)
|
||||||
|
switch(argv[i][i2])
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\a');
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\b');
|
||||||
|
break;
|
||||||
|
case 'c': // Immediately stop execution.
|
||||||
|
goto end;
|
||||||
|
case 'f':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\f');
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\n');
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\r');
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\t');
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\v');
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
escape = 0;
|
||||||
|
putchar('\\');
|
||||||
|
break;
|
||||||
|
case '0': // This is for octal values.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(argv[i][i2] == '\\')
|
||||||
|
escape++;
|
||||||
|
else
|
||||||
|
putchar(argv[i][i2]);
|
||||||
|
}
|
||||||
|
if(i < (argc-1))
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
end:
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
o
|
180
proto/ls.c
Normal file
180
proto/ls.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "../src/support.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* pars -- end with L is lowercase par, end with U is uppercase, non-alpha spelled out */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
AL,
|
||||||
|
AU,
|
||||||
|
CL,
|
||||||
|
CU,
|
||||||
|
DL,
|
||||||
|
FL,
|
||||||
|
FU,
|
||||||
|
GL,
|
||||||
|
IL,
|
||||||
|
KL,
|
||||||
|
LL,
|
||||||
|
ML,
|
||||||
|
NL,
|
||||||
|
OL,
|
||||||
|
PL,
|
||||||
|
QL,
|
||||||
|
RL,
|
||||||
|
RU,
|
||||||
|
SL,
|
||||||
|
SU,
|
||||||
|
TL,
|
||||||
|
UL,
|
||||||
|
XL,
|
||||||
|
ONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char pars[23] = {0};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DIR *dp;
|
||||||
|
struct dirent *dirp;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
dp = 0;
|
||||||
|
dirp = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* process our parameters */
|
||||||
|
for(; (i = getopt(argc, argv, "ikqrsglnoAaCmx1FpHLRdSftcu")) != -1; i = 0)
|
||||||
|
{
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 'a': pars[AL] = 1;
|
||||||
|
pars[AU] = 0;
|
||||||
|
break;
|
||||||
|
case 'A': pars[AU] = 1;
|
||||||
|
pars[AL] = 0;
|
||||||
|
break;
|
||||||
|
case 'c': pars[CL] = 1;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
if(pars[ML] || pars[XL] || pars[ONE] )
|
||||||
|
{
|
||||||
|
throw(NEEDARG_FAIL, " ls [-ikqrsglno] [-A|-a] [-C|-m|-x|-l]\n\t[-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [path ...]");
|
||||||
|
}
|
||||||
|
pars[CU] = 1;
|
||||||
|
break;
|
||||||
|
case 'd': pars[DL] = 1;
|
||||||
|
pars[RU] = 0;
|
||||||
|
break;
|
||||||
|
case 'f': pars[FL] = 1;
|
||||||
|
pars[SU] = 0;
|
||||||
|
pars[TL] = 0;
|
||||||
|
break;
|
||||||
|
case 'F': pars[FU] = 1;
|
||||||
|
pars[PL] = 0;
|
||||||
|
break;
|
||||||
|
case 'g': pars[GL] = 1;
|
||||||
|
break;
|
||||||
|
case 'i': pars[IL] = 1;
|
||||||
|
break;
|
||||||
|
case 'k': pars[KL] = 1;
|
||||||
|
break;
|
||||||
|
case 'l': pars[LL] = 1;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
if(pars[CU] || pars[XL] || pars[ONE] )
|
||||||
|
{
|
||||||
|
throw(NEEDARG_FAIL, " ls [-ikqrsglno] [-A|-a] [-C|-m|-x|-l]\n\t[-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [path ...]");
|
||||||
|
}
|
||||||
|
pars[ML] = 1;
|
||||||
|
pars[CU] = 0;
|
||||||
|
pars[XL] = 0;
|
||||||
|
pars[ONE] = 0;
|
||||||
|
break;
|
||||||
|
case 'n': pars[NL] = 1;
|
||||||
|
break;
|
||||||
|
case 'o': pars[OL] = 1;
|
||||||
|
break;
|
||||||
|
case 'p': pars[PL] = 1;
|
||||||
|
pars[FU] = 0;
|
||||||
|
break;
|
||||||
|
case 'q': pars[QL] = 1;
|
||||||
|
break;
|
||||||
|
case 'r': pars[RL] = 1;
|
||||||
|
break;
|
||||||
|
case 'R': pars[RU] = 1;
|
||||||
|
pars[DL] = 0;
|
||||||
|
break;
|
||||||
|
case 's': pars[SL] = 1;
|
||||||
|
break;
|
||||||
|
case 'S': pars[SU] = 1;
|
||||||
|
pars[FL] = 0;
|
||||||
|
pars[TL] = 0;
|
||||||
|
break;
|
||||||
|
case 't': pars[TL] = 1;
|
||||||
|
pars[SU] = 0;
|
||||||
|
pars[FL] = 0;
|
||||||
|
break;
|
||||||
|
case 'u': pars[UL] = 1;
|
||||||
|
pars[CL] = 0;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
if(pars[ML] || pars[CU] || pars[ONE] )
|
||||||
|
{
|
||||||
|
throw(NEEDARG_FAIL, " ls [-ikqrsglno] [-A|-a] [-C|-m|-x|-l]\n\t[-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [path ...]");
|
||||||
|
}
|
||||||
|
pars[XL] = 1;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
if(pars[ML] || pars[XL] || pars[CU] )
|
||||||
|
{
|
||||||
|
throw(NEEDARG_FAIL, " ls [-ikqrsglno] [-A|-a] [-C|-m|-x|-l]\n\t[-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [path ...]");
|
||||||
|
}
|
||||||
|
pars[ONE] = 1;
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
case '?':
|
||||||
|
default: throw(NEEDARG_FAIL, mastrcat(argv[0], " ls [-ikqrsglno] [-A|-a] [-C|-m|-x|-l]\n\t[-F|-p] [-H|-L] [-R|-d] [-S|-f|-t] [-c|-u] [path ...]"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = optind;
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(!argv[i])
|
||||||
|
{
|
||||||
|
argv[i] = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !(dp = opendir(argv[i])))
|
||||||
|
{
|
||||||
|
throw(MISC_FAIL, mastrcat(argv[0], mastrcat(": could not access named file or directory: ", argv[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;(dirp = readdir(dp));)
|
||||||
|
{
|
||||||
|
if(dirp->d_name[0] == '.' && !pars[AL])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("%s\n", dirp->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while(i < argc);
|
||||||
|
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
@ -14,6 +14,13 @@ BIN = cat\
|
|||||||
echo\
|
echo\
|
||||||
wc\
|
wc\
|
||||||
|
|
||||||
|
MAN = \
|
||||||
|
cat.1 \
|
||||||
|
false.1 \
|
||||||
|
true.1 \
|
||||||
|
yes.1 \
|
||||||
|
echo.1 \
|
||||||
|
wc.1 \
|
||||||
|
|
||||||
all: ${BIN}
|
all: ${BIN}
|
||||||
false: true
|
false: true
|
||||||
@ -21,7 +28,9 @@ false: true
|
|||||||
|
|
||||||
install: all
|
install: all
|
||||||
mkdir -p ${DESTDIR}/${PREFIX}/bin
|
mkdir -p ${DESTDIR}/${PREFIX}/bin
|
||||||
|
mkdir -p ${DESTDIR}/${PREFIX}/share/man/man.1
|
||||||
install -Dm0755 ${BIN} ${DESTDIR}/${PREFIX}/bin/
|
install -Dm0755 ${BIN} ${DESTDIR}/${PREFIX}/bin/
|
||||||
|
install -Dm0644 ${MAN} ${DESTDIR}/${PREFIX}/share/man/man.1/
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm ${BIN} *.o
|
rm ${BIN} *.o
|
||||||
|
109
src/cat.c
109
src/cat.c
@ -1,115 +1,78 @@
|
|||||||
/* cat.c -- program to concatenate named files and/or stdin onto stdout */
|
/* cat -- third revision of a program to concatenate files and/or stdin onto */
|
||||||
/* version 2 */
|
/* stdout */
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
|
|
||||||
|
|
||||||
/* parameters */
|
/* Params */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
U
|
U
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* concat - return a buffer of size new_size containing s1 and s2 concatenated. */
|
|
||||||
char *concat(char *a1, char *a2, int a1_size, int a2_size)
|
|
||||||
{
|
|
||||||
char *newbuf;
|
|
||||||
|
|
||||||
newbuf = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if( !(newbuf = malloc(a1_size+a2_size)))
|
|
||||||
{
|
|
||||||
throw(MALLOC_FAIL, "concat: couldn't create buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(a1_size)
|
|
||||||
{
|
|
||||||
mid_mempcpy(newbuf, a1, a1_size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(a2_size)
|
|
||||||
{
|
|
||||||
mid_mempcpy(newbuf, a2, a2_size, a1_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return(newbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, c, bufsize, newbufsize;
|
int i, i2;
|
||||||
|
|
||||||
char *buf, *newbuf;
|
|
||||||
char pars[1] = {0};
|
|
||||||
|
|
||||||
|
char param_state[1] = {0};
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
|
||||||
i = c = bufsize = newbufsize = 0;
|
i = i2 = 0;
|
||||||
|
|
||||||
buf = newbuf = 0;
|
|
||||||
|
|
||||||
fd = 0;
|
fd = 0;
|
||||||
|
|
||||||
|
|
||||||
/* process our parameters */
|
for(; (i = getopt(argc, argv, "u")) != -1;)
|
||||||
for(; (c = getopt(argc, argv, "u")) != -1; c = 0)
|
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(i)
|
||||||
{
|
{
|
||||||
case 'u': pars[U] = 1;
|
case 'u':
|
||||||
break;
|
param_state[U] = 1;
|
||||||
case ':':
|
|
||||||
case '?':
|
|
||||||
default: throw(NEEDARG_FAIL, mastrcat(argv[0], " [-u] [file ...]"));
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw(NEEDARG_FAIL, mastrcat(argv[0], " [-u] [file ...]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = optind;
|
i = optind;
|
||||||
|
|
||||||
|
if(param_state[U])
|
||||||
/* i < argc is obvious; steps through all provided args. */
|
|
||||||
/* !argc-optind && !c is a little less so - it allows this loop to run once if the user provides no paths */
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if( !(fd = file_open(argv[i], "r")))
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
{
|
}
|
||||||
throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i])));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pars[U])
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(argv[i] == NULL || !strcmp("-", argv[i]))
|
||||||
{
|
{
|
||||||
for(; (c = fgetc(fd)) != EOF; c = 0)
|
fd = fopen("/dev/stdin", "r");
|
||||||
{
|
|
||||||
fputc(c, stdout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newbuf = file_read(fd, &newbufsize);
|
if( !(fd = fopen(argv[i], "r")))
|
||||||
buf = concat(buf, newbuf, bufsize, newbufsize);
|
{
|
||||||
bufsize += newbufsize;
|
throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i])));
|
||||||
free(newbuf);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i++, newbufsize = 0;
|
|
||||||
}
|
|
||||||
while((i < argc) || (((argc - optind) == 0) && !c));
|
|
||||||
|
|
||||||
if(!pars[U])
|
for(i2 = 0; (i2 = fgetc(fd)) != EOF; i2 = 0)
|
||||||
{
|
{
|
||||||
fwrite(buf, sizeof(char), bufsize, stdout);
|
fputc(i2, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while(i < argc);
|
||||||
|
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
145
src/echo.c
145
src/echo.c
@ -1,65 +1,102 @@
|
|||||||
|
/* echo -- version two */
|
||||||
|
/* program to print argument vector to stdout while escaping BEL, tab, backspace and others */
|
||||||
|
/* mostly SUS compliant */
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
|
|
||||||
|
|
||||||
|
void escape(char c)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
fputc('\a', stdout);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
fputc('\b', stdout);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
fputc('\f', stdout);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
fputc('\n', stdout);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
fputc('\r', stdout);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
fputc('\t', stdout);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
fputc('\v', stdout);
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
fputc('\\', stdout);
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fputc('\\', stdout);
|
||||||
|
fputc(c, stdout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char esc_state;
|
||||||
|
|
||||||
int i, i2;
|
int i, i2;
|
||||||
char escape = 0;
|
|
||||||
|
|
||||||
if(argc > 1)
|
|
||||||
for(i = 1; i < argc; i++)
|
esc_state = 0;
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
i2 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for(; i < argc; i++)
|
||||||
|
{
|
||||||
|
for(i2 = 0; argv[i][i2] != '\0'; i2++)
|
||||||
{
|
{
|
||||||
for(i2 = 0; argv[i][i2] != '\0'; i2++)
|
if(!esc_state && '\\' == argv[i][i2])
|
||||||
{
|
{
|
||||||
if(escape)
|
esc_state = 1;
|
||||||
switch(argv[i][i2])
|
|
||||||
{
|
|
||||||
case 'a':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\a');
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\b');
|
|
||||||
break;
|
|
||||||
case 'c': // Immediately stop execution.
|
|
||||||
goto end;
|
|
||||||
case 'f':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\f');
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\n');
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\r');
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\t');
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\v');
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
escape = 0;
|
|
||||||
putchar('\\');
|
|
||||||
break;
|
|
||||||
case '0': // This is for octal values.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(argv[i][i2] == '\\')
|
|
||||||
escape++;
|
|
||||||
else
|
|
||||||
putchar(argv[i][i2]);
|
|
||||||
}
|
}
|
||||||
if(i < (argc-1))
|
else if(esc_state)
|
||||||
putchar(' ');
|
{
|
||||||
}
|
esc_state = 0;
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
end:
|
escape(argv[i][i2]);
|
||||||
return 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputc(argv[i][i2], stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(esc_state)
|
||||||
|
{
|
||||||
|
esc_state = 0;
|
||||||
|
|
||||||
|
fputc('\\', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((i + 1) != argc)
|
||||||
|
{
|
||||||
|
fputc(' ', stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fputc('\n', stdout);
|
||||||
|
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,5 +39,5 @@ int main(int argc, char **argv)
|
|||||||
sleep(i);
|
sleep(i);
|
||||||
|
|
||||||
|
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -70,21 +70,6 @@ void throw(long unsigned int condition, void *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mid_mempcpy -- copy n bytes from s2 to s1 starting at position p */
|
|
||||||
int mid_mempcpy(char *s1, char *s2, int n, int p)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i <= n; i++, p++)
|
|
||||||
{
|
|
||||||
s1[p] = s2[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */
|
/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */
|
||||||
/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */
|
/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */
|
||||||
@ -207,3 +192,63 @@ char *file_read(FILE *fd, int *newsize)
|
|||||||
*newsize = i;
|
*newsize = i;
|
||||||
return(buf);
|
return(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
node *node_create()
|
||||||
|
{
|
||||||
|
node *newnode;
|
||||||
|
|
||||||
|
newnode = 0;
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
return(newnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int node_free(node *todel)
|
||||||
|
{
|
||||||
|
node *nodep;
|
||||||
|
|
||||||
|
|
||||||
|
nodep = todel->previous;
|
||||||
|
nodep->next = todel->next;
|
||||||
|
|
||||||
|
|
||||||
|
free(todel->name);
|
||||||
|
free(todel->data);
|
||||||
|
free(todel);
|
||||||
|
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* concat - return a buffer of size new_size containing s1 and s2 concatenated. */
|
||||||
|
char *concat(char *a1, char *a2, int a1_size, int a2_size)
|
||||||
|
{
|
||||||
|
char *newbuf;
|
||||||
|
|
||||||
|
newbuf = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if( !(newbuf = malloc(a1_size+a2_size)))
|
||||||
|
{
|
||||||
|
throw(MALLOC_FAIL, "concat: couldn't create buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(a1_size)
|
||||||
|
{
|
||||||
|
memcpy(newbuf, a1, a1_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(a2_size)
|
||||||
|
{
|
||||||
|
memcpy((newbuf + a1_size), a2, a2_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return(newbuf);
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if(!strcmp(argv[0], "true"))
|
if(!strcmp(argv[0], "true"))
|
||||||
return 0;
|
exit(EXIT_SUCCESS);
|
||||||
else
|
else
|
||||||
return 1;
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user