diff --git a/TODO b/TODO index 4702203..aef57a2 100644 --- a/TODO +++ b/TODO @@ -14,20 +14,19 @@ Simple commands (only a handful of parameters at most, with simple premises) -yes [done] -basename/dirname -echo [in-progress, SUS] --wc [in-progress] +-wc [done] -tee -cat [done] -pwd -cksum -cal -Filesystem modifiers +Filesystem interfaces -rm -mv -cp -mkdir -rmdir --mktemp -chgrp -chown -chmod diff --git a/doc/cat.1 b/doc/cat.1 index 6f7ae0e..8a73746 100644 --- a/doc/cat.1 +++ b/doc/cat.1 @@ -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 cat \- concatenate input .PP @@ -12,7 +12,7 @@ including stdin. It then concatenates (attached end to end) each bit of input, before printing it to stdout. .SH OPTIONS .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. diff --git a/doc/echo.1 b/doc/echo.1 index 797d3ee..32dd157 100644 --- a/doc/echo.1 +++ b/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 echo \- Print argv to stdout. .PP @@ -10,10 +10,28 @@ SUS backslash escapes. .SH DESCRIPTION .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 .PP -This implementation of echo accepts no arguments. +This implementation of echo accepts no parameters. .SH ENVIRONMENT This implementation of echo requires a C89 compiler. .SH FILES @@ -28,24 +46,7 @@ SUS 3 .SH NOTES .PP -Including the following backslash-escapes modifies echo's behavior. - -\\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. - +For historical reasons implementations of echo vary wildly in their behavior across systems. For a portable way to print to stdout, see printf. .SH BUGS .PP Currently, \\0xxx (octal) escapes have not been implemented. diff --git a/doc/false.1 b/doc/false.1 new file mode 100644 index 0000000..2394dde --- /dev/null +++ b/doc/false.1 @@ -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) diff --git a/doc/sleep.1 b/doc/sleep.1 new file mode 100644 index 0000000..91e2b15 --- /dev/null +++ b/doc/sleep.1 @@ -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) diff --git a/doc/template b/doc/template deleted file mode 100644 index 2f603f5..0000000 --- a/doc/template +++ /dev/null @@ -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) \ No newline at end of file diff --git a/doc/true.1 b/doc/true.1 new file mode 100644 index 0000000..2c4e50f --- /dev/null +++ b/doc/true.1 @@ -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) diff --git a/doc/wc.1 b/doc/wc.1 index e0befc3..265267b 100644 --- a/doc/wc.1 +++ b/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 wc \- count words, lines, bytes/characters .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. .SH OPTIONS .PP -This implementation of wc accepts the following arguments: +This implementation of wc accepts the following flags: .SM -c: Print the number of bytes. diff --git a/doc/yes.1 b/doc/yes.1 index 954cfa7..e7ccc6e 100644 --- a/doc/yes.1 +++ b/doc/yes.1 @@ -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 yes \- print to stdout forever .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. .SH OPTIONS .PP -This implementation of yes accepts no arguments. +This implementation of yes accepts no flags. .SH ENVIRONMENT This implementation of yes requires a C89 compiler. .SH FILES diff --git a/old/cat2.c b/old/cat2.c new file mode 100644 index 0000000..f1253dc --- /dev/null +++ b/old/cat2.c @@ -0,0 +1,72 @@ +/* cat.c -- program to concatenate named files and/or stdin onto stdout */ +/* version 2 */ + + +#include +#include +#include +#include + +#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); + } diff --git a/old/echo.c b/old/echo.c new file mode 100644 index 0000000..7101ba7 --- /dev/null +++ b/old/echo.c @@ -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 diff --git a/proto/ls.c b/proto/ls.c new file mode 100644 index 0000000..45569e9 --- /dev/null +++ b/proto/ls.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include + +#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); + } diff --git a/src/Makefile b/src/Makefile index 312b221..3a9df53 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,6 +14,13 @@ BIN = cat\ echo\ wc\ +MAN = \ + cat.1 \ + false.1 \ + true.1 \ + yes.1 \ + echo.1 \ + wc.1 \ all: ${BIN} false: true @@ -21,7 +28,9 @@ false: true install: all mkdir -p ${DESTDIR}/${PREFIX}/bin + mkdir -p ${DESTDIR}/${PREFIX}/share/man/man.1 install -Dm0755 ${BIN} ${DESTDIR}/${PREFIX}/bin/ + install -Dm0644 ${MAN} ${DESTDIR}/${PREFIX}/share/man/man.1/ clean: rm ${BIN} *.o diff --git a/src/cat.c b/src/cat.c index d9f1672..2174ca0 100644 --- a/src/cat.c +++ b/src/cat.c @@ -1,115 +1,78 @@ -/* cat.c -- program to concatenate named files and/or stdin onto stdout */ -/* version 2 */ +/* cat -- third revision of a program to concatenate files and/or stdin onto */ +/* stdout */ #include #include +#include #include #include #include "support.h" -/* parameters */ +/* Params */ enum { 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 i, c, bufsize, newbufsize; - - char *buf, *newbuf; - char pars[1] = {0}; + int i, i2; + char param_state[1] = {0}; FILE *fd; - i = c = bufsize = newbufsize = 0; - - buf = newbuf = 0; + i = i2 = 0; fd = 0; - /* process our parameters */ - for(; (c = getopt(argc, argv, "u")) != -1; c = 0) + for(; (i = getopt(argc, argv, "u")) != -1;) { - switch(c) + switch(i) { - case 'u': pars[U] = 1; - break; - case ':': - case '?': - default: throw(NEEDARG_FAIL, mastrcat(argv[0], " [-u] [file ...]")); + case 'u': + param_state[U] = 1; break; + default: + throw(NEEDARG_FAIL, mastrcat(argv[0], " [-u] [file ...]")); } } i = optind; - - /* 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(param_state[U]) { - if( !(fd = file_open(argv[i], "r"))) - { - throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i]))); - } + setvbuf(stdout, NULL, _IONBF, 0); + } - if(pars[U]) + + do + { + if(argv[i] == NULL || !strcmp("-", argv[i])) { - for(; (c = fgetc(fd)) != EOF; c = 0) - { - fputc(c, stdout); - } + fd = fopen("/dev/stdin", "r"); } else { - newbuf = file_read(fd, &newbufsize); - buf = concat(buf, newbuf, bufsize, newbufsize); - bufsize += newbufsize; - free(newbuf); + if( !(fd = fopen(argv[i], "r"))) + { + throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i]))); + } } - i++, newbufsize = 0; - } - while((i < argc) || (((argc - optind) == 0) && !c)); - if(!pars[U]) - { - fwrite(buf, sizeof(char), bufsize, stdout); - } + for(i2 = 0; (i2 = fgetc(fd)) != EOF; i2 = 0) + { + fputc(i2, stdout); + } + - exit(0); + i++; + } + while(i < argc); + + + exit(EXIT_SUCCESS); } diff --git a/src/echo.c b/src/echo.c index c6e70d4..dc62aaf 100644 --- a/src/echo.c +++ b/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 +#include + #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) { + char esc_state; + 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) - 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]); + esc_state = 1; } - if(i < (argc-1)) - putchar(' '); - } - putchar('\n'); + else if(esc_state) + { + esc_state = 0; - end: - return 0; + escape(argv[i][i2]); + } + 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); } + diff --git a/src/sleep.c b/src/sleep.c index b560a59..368ba15 100644 --- a/src/sleep.c +++ b/src/sleep.c @@ -39,5 +39,5 @@ int main(int argc, char **argv) sleep(i); - exit(0); + exit(EXIT_SUCCESS); } diff --git a/src/support.h b/src/support.h index ee88df5..c92e804 100644 --- a/src/support.h +++ b/src/support.h @@ -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 */ /* 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; 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); + } diff --git a/src/true.c b/src/true.c index 29c5f69..d77de4a 100644 --- a/src/true.c +++ b/src/true.c @@ -3,7 +3,7 @@ int main(int argc, char **argv) { if(!strcmp(argv[0], "true")) - return 0; + exit(EXIT_SUCCESS); else - return 1; + exit(EXIT_FAILURE); } diff --git a/src/wc.c b/src/wc.c index 0990906..940cf13 100644 --- a/src/wc.c +++ b/src/wc.c @@ -190,5 +190,5 @@ int main(int argc, char **argv) while((i+=1) < argc); - exit(0); + exit(EXIT_SUCCESS); }