Eliminating the getopt disgrace.

This commit is contained in:
Christoph Lohmann 2013-06-14 20:20:47 +02:00
parent 75c97de593
commit 4d38f60685
28 changed files with 724 additions and 476 deletions

36
chmod.c
View File

@ -13,26 +13,32 @@ static bool rflag = false;
static char oper = '='; static char oper = '=';
static mode_t mode = 0; static mode_t mode = 0;
static void
usage(void)
{
eprintf("usage: %s [-r] mode [file...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
while((c = getopt(argc, argv, "r")) != -1) ARGBEGIN {
switch(c) { case 'r':
case 'r': rflag = true;
rflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
if(optind == argc)
eprintf("usage: %s [-r] mode [file...]\n", argv[0]);
parsemode(argv[optind++]); if(argc < 1)
for(; optind < argc; optind++) usage();
chmodr(argv[optind]);
return EXIT_SUCCESS; parsemode(argv[0]);
for(++argv; argc > 0; argc--)
chmodr(argv[0]);
return 0;
} }
void void

40
chown.c
View File

@ -14,22 +14,30 @@ static bool rflag = false;
static struct passwd *pw = NULL; static struct passwd *pw = NULL;
static struct group *gr = NULL; static struct group *gr = NULL;
static void
usage(void)
{
eprintf("usage: %s [-r] [owner][:[group]] file...\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c, *owner, *group; char *owner, *group;
while((c = getopt(argc, argv, "r")) != -1) ARGBEGIN {
switch(c) { case 'r':
case 'r': rflag = true;
rflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
} if(argc == 0)
if(optind == argc) usage();
eprintf("usage: %s [-r] [owner][:group] [file...]\n", argv[0]);
owner = argv[optind++]; owner = argv[0];
argv++;
if((group = strchr(owner, ':'))) if((group = strchr(owner, ':')))
*group++ = '\0'; *group++ = '\0';
@ -49,9 +57,10 @@ main(int argc, char *argv[])
else if(!gr) else if(!gr)
eprintf("getgrnam %s: no such group\n", group); eprintf("getgrnam %s: no such group\n", group);
} }
for(; optind < argc; optind++) for(; argc > 0; argc--, argv++)
chownpwgr(argv[optind]); chownpwgr(argv[0]);
return EXIT_SUCCESS;
return 0;
} }
void void
@ -63,3 +72,4 @@ chownpwgr(const char *path)
if(rflag) if(rflag)
recurse(path, chownpwgr); recurse(path, chownpwgr);
} }

53
cmp.c
View File

@ -7,51 +7,60 @@
enum { Same = 0, Diff = 1, Error = 2 }; enum { Same = 0, Diff = 1, Error = 2 };
static void
usage(void)
{
enprintf(Error, "usage: %s [-ls] file1 file2\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
bool lflag = false; bool lflag = false;
bool sflag = false; bool sflag = false;
bool same = true; bool same = true;
char c;
int b[2], i; int b[2], i;
long line = 1, n = 1; long line = 1, n = 1;
FILE *fp[2]; FILE *fp[2];
if((c = getopt(argc, argv, "ls")) != -1) ARGBEGIN {
switch(c) { case 'l':
case 'l': lflag = true;
lflag = true; break;
break; case 's':
case 's': sflag = true;
sflag = true; break;
break; default:
default: usage();
exit(Error); } ARGEND;
}
if(optind != argc-2) if(argc < 2)
enprintf(Error, "usage: %s [-ls] file1 file2\n", argv[0]); usage();
for(i = 0; i < 2; i++)
if(!(fp[i] = fopen(argv[optind+i], "r"))) for(i = 0; i < 2; i++) {
enprintf(Error, "fopen %s:", argv[optind+i]); if(!(fp[i] = fopen(argv[i], "r")))
for(n = 1; ((b[0] = getc(fp[0])) != EOF) | ((b[1] = getc(fp[1])) != EOF); n++) { enprintf(Error, "fopen %s:", argv[i]);
}
for(n = 1; ((b[0] = getc(fp[0])) != EOF) \
| ((b[1] = getc(fp[1])) != EOF); n++) {
if(b[0] == '\n') if(b[0] == '\n')
line++; line++;
if(b[0] == b[1]) if(b[0] == b[1])
continue; continue;
for(i = 0; i < 2; i++) for(i = 0; i < 2; i++)
if(b[i] == EOF) if(b[i] == EOF)
enprintf(Diff, "cmp: EOF on %s\n", argv[optind+i]); enprintf(Diff, "cmp: EOF on %s\n", argv[i]);
if(!lflag) { if(!lflag) {
if(!sflag) if(!sflag)
printf("%s %s differ: char %ld, line %ld\n", printf("%s %s differ: char %ld, line %ld\n",
argv[optind], argv[optind+1], n, line); argv[0], argv[1], n, line);
exit(Diff); exit(Diff);
} } else {
else {
printf("%4ld %3o %3o\n", n, b[0], b[1]); printf("%4ld %3o %3o\n", n, b[0], b[1]);
same = false; same = false;
} }
} }
return same ? Same : Diff; return same ? Same : Diff;
} }

40
date.c
View File

@ -5,10 +5,17 @@
#include <unistd.h> #include <unistd.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-u] [-d format] [+FORMAT]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char buf[BUFSIZ], c; char buf[BUFSIZ];
char *fmt = "%c"; char *fmt = "%c";
struct tm *now = NULL; struct tm *now = NULL;
struct tm *(*tztime)(const time_t *) = localtime; struct tm *(*tztime)(const time_t *) = localtime;
@ -16,24 +23,25 @@ main(int argc, char *argv[])
time_t t; time_t t;
t = time(NULL); t = time(NULL);
while((c = getopt(argc, argv, "d:u")) != -1) ARGBEGIN {
switch(c) { case 'd':
case 'd': t = estrtol(EARGF(usage()), 0);
t = estrtol(optarg, 0); break;
break; case 'u':
case 'u': tztime = gmtime;
tztime = gmtime; tz = "gm";
tz = "gm"; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
} if(argc > 0 && argv[0][0] == '+')
if(optind < argc && argv[optind][0] == '+') fmt = &argv[0][1];
fmt = &argv[optind][1];
if(!(now = tztime(&t))) if(!(now = tztime(&t)))
eprintf("%stime failed\n", tz); eprintf("%stime failed\n", tz);
strftime(buf, sizeof buf, fmt, now); strftime(buf, sizeof buf, fmt, now);
puts(buf); puts(buf);
return EXIT_SUCCESS;
return 0;
} }

View File

@ -5,14 +5,26 @@
#include <unistd.h> #include <unistd.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s string\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
if(getopt(argc, argv, "") != -1) ARGBEGIN {
exit(EXIT_FAILURE); default:
if(optind != argc-1) usage();
eprintf("usage: %s string\n", argv[0]); } ARGEND;
if(argc < 1)
usage();
puts(dirname(argv[optind])); puts(dirname(argv[optind]));
return EXIT_SUCCESS;
return 0;
} }

32
echo.c
View File

@ -5,23 +5,31 @@
#include <unistd.h> #include <unistd.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-n] text\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
bool nflag = false; bool nflag = false;
char c;
while((c = getopt(argc, argv, "n")) != -1) ARGBEGIN {
switch(c) { case 'n':
case 'n': nflag = true;
nflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
for(; optind < argc; optind++) for(; argc > 0; argc--, argv++)
putword(argv[optind]); putword(argv[0]);
if(!nflag) if(!nflag)
putchar('\n'); putchar('\n');
return EXIT_SUCCESS;
return 0;
} }

48
fold.c
View File

@ -13,36 +13,43 @@ static void foldline(const char *, long);
static bool bflag = false; static bool bflag = false;
static bool sflag = false; static bool sflag = false;
static void
usage(void)
{
eprintf("usage: %s [-bs] [-w width] [FILE...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
long width = 80; long width = 80;
FILE *fp; FILE *fp;
while((c = getopt(argc, argv, "bsw:")) != -1) ARGBEGIN {
switch(c) { case 'b':
case 'b': bflag = true;
bflag = true; break;
break; case 's':
case 's': sflag = true;
sflag = true; break;
break; case 'w':
case 'w': width = estrtol(EARGF(usage()), 0);
width = estrtol(optarg, 0); break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
if(optind == argc) if(argc == 0) {
fold(stdin, width); fold(stdin, width);
else for(; optind < argc; optind++) { } else for(; argc > 0; argc--, argv++) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
fold(fp, width); fold(fp, width);
fclose(fp); fclose(fp);
} }
return EXIT_SUCCESS;
return 0;
} }
void void
@ -96,3 +103,4 @@ foldline(const char *str, long width)
putchar('\n'); putchar('\n');
} while(str[i = n] && str[i] != '\n'); } while(str[i = n] && str[i] != '\n');
} }

38
head.c
View File

@ -7,30 +7,37 @@
static void head(FILE *, const char *, long); static void head(FILE *, const char *, long);
static void
usage(void)
{
eprintf("usage: %s [-n] [FILE...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
long n = 10; long n = 10;
FILE *fp; FILE *fp;
while((c = getopt(argc, argv, "n:")) != -1) ARGBEGIN {
switch(c) { case 'n':
case 'n': n = estrtol(EARGF(usage()), 0);
n = estrtol(optarg, 0); break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
if(optind == argc) if(argc == 0) {
head(stdin, "<stdin>", n); head(stdin, "<stdin>", n);
else for(; optind < argc; optind++) { } else for(; argc > 0; argc--, argv++) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
head(fp, argv[optind], n); head(fp, argv[0], n);
fclose(fp); fclose(fp);
} }
return EXIT_SUCCESS;
return 0;
} }
void void
@ -47,3 +54,4 @@ head(FILE *fp, const char *str, long n)
if(ferror(fp)) if(ferror(fp))
eprintf("%s: read error:", str); eprintf("%s: read error:", str);
} }

64
kill.c
View File

@ -19,60 +19,62 @@ struct {
#undef SIG #undef SIG
}; };
static void usage(void); static void
usage(void)
{
eprintf("usage: %s [-s signal] [pid...]\n"
" %s -l [signum]\n", argv0, argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
bool lflag = false; bool lflag = false;
char c, *end; char *end, *v;
int sig = SIGTERM; int sig = SIGTERM;
pid_t pid; pid_t pid;
size_t i; size_t i;
while((c = getopt(argc, argv, "ls:")) != -1) ARGBEGIN {
switch(c) { case 'l':
case 'l': lflag = true;
lflag = true; break;
case 's':
v = EARGF(usage());
sig = strtol(v, &end, 0);
if(*end == '\0')
break; break;
case 's': for(i = 0; i < LEN(sigs); i++) {
sig = strtol(optarg, &end, 0); if(!strcasecmp(v, sigs[i].name)) {
if(*end == '\0') sig = sigs[i].sig;
break; break;
for(i = 0; i < LEN(sigs); i++) }
if(!strcasecmp(optarg, sigs[i].name)) {
sig = sigs[i].sig;
break;
}
if(i == LEN(sigs))
eprintf("%s: unknown signal\n", optarg);
break;
default:
usage();
} }
if(optind < argc-1) if(i == LEN(sigs))
eprintf("%s: unknown signal\n", v);
break;
default:
usage();
} ARGEND;
if(argc < 2)
usage(); usage();
if(lflag) { if(lflag) {
sig = (optind == argc) ? 0 : estrtol(argv[optind], 0); sig = (argc > 0) ? 0 : estrtol(argv[0], 0);
if(sig > 128) if(sig > 128)
sig = WTERMSIG(sig); sig = WTERMSIG(sig);
for(i = 0; i < LEN(sigs); i++) for(i = 0; i < LEN(sigs); i++)
if(sigs[i].sig == sig || sig == 0) if(sigs[i].sig == sig || sig == 0)
putword(sigs[i].name); putword(sigs[i].name);
putchar('\n'); putchar('\n');
} } else for(; argc > 0; argc--, argv++) {
else for(; optind < argc; optind++) { pid = estrtol(argv[0], 0);
pid = estrtol(argv[optind], 0);
if(kill(pid, sig) == -1) if(kill(pid, sig) == -1)
eprintf("kill %d:", pid); eprintf("kill %d:", pid);
} }
return EXIT_SUCCESS;
return 0;
} }
void
usage(void)
{
eprintf("usage: %s [-s signal] [pid...]\n"
" %s -l [signum]\n", argv0, argv0);
}

35
ln.c
View File

@ -11,24 +11,30 @@ static int ln(const char *, const char *);
static bool sflag = false; static bool sflag = false;
static bool fflag = false; static bool fflag = false;
static void
usage(void)
{
eprintf("usage: %s [-fs] target linkname\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c; ARGBEGIN {
case 'f':
fflag = true;
break;
case 's':
sflag = true;
break;
default:
usage();
} ARGEND;
while((c = getopt(argc, argv, "fs")) != -1) enmasse(argc, &argv[0], ln);
switch(c) {
case 'f': return 0;
fflag = true;
break;
case 's':
sflag = true;
break;
default:
exit(EXIT_FAILURE);
}
enmasse(argc - optind, &argv[optind], ln);
return EXIT_SUCCESS;
} }
int int
@ -45,3 +51,4 @@ ln(const char *s1, const char *s2)
} }
return -1; return -1;
} }

55
ls.c
View File

@ -35,44 +35,52 @@ static bool tflag = false;
static bool first = true; static bool first = true;
static bool many; static bool many;
static void
usage(void)
{
eprintf("usage: %s [-adlt] [FILE...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
int i, n; int i, n;
Entry *ents; Entry *ents;
while((c = getopt(argc, argv, "adlt")) != -1) ARGBEGIN {
switch(c) { case 'a':
case 'a': aflag = true;
aflag = true; break;
break; case 'd':
case 'd': dflag = true;
dflag = true; break;
break; case 'l':
case 'l': lflag = true;
lflag = true; break;
break; case 't':
case 't': tflag = true;
tflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
many = (argc > optind+1);
if((n = argc - optind) > 0) { many = (argc > 1);
if((n = argc) > 0) {
if(!(ents = malloc(n * sizeof *ents))) if(!(ents = malloc(n * sizeof *ents)))
eprintf("malloc:"); eprintf("malloc:");
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
mkent(&ents[i], argv[optind+i]); mkent(&ents[i], argv[i]);
qsort(ents, n, sizeof *ents, (int (*)(const void *, const void *))entcmp); qsort(ents, n, sizeof *ents,
(int (*)(const void *, const void *))entcmp);
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
ls(ents[i].name); ls(ents[i].name);
} }
else else
ls("."); ls(".");
return EXIT_SUCCESS;
return 0;
} }
int int
@ -229,3 +237,4 @@ output(Entry *ent)
} }
putchar('\n'); putchar('\n');
} }

39
mc.c
View File

@ -14,32 +14,37 @@ static struct linebuf b = EMPTY_LINEBUF;
static long n_columns; static long n_columns;
static long n_rows; static long n_rows;
static void
usage(void)
{
eprintf("usage: %s [-c chars] [FILE...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int c;
long i, l, col; long i, l, col;
size_t maxlen = 0; size_t maxlen = 0;
char *space; char *space;
FILE *fp; FILE *fp;
while ((c = getopt(argc, argv, "c:")) != -1) ARGBEGIN {
switch (c) { case 'c':
case 'c': chars = estrtol(EARGF(usage()), 0);
chars = estrtol(optarg, 0); if(chars < 3)
if (chars < 3) eprintf("%d: too few character columns");
eprintf("%d: too few character columns"); break;
break; default:
default: usage();
exit(2); } ARGEND;
}
/* XXX librarify this chunk, too? only useful in sponges though */ /* XXX librarify this chunk, too? only useful in sponges though */
if(optind == argc) if(argc == 0) {
getlines(stdin, &b); getlines(stdin, &b);
else for(; optind < argc; optind++) { } else for(; argc > 0; argc--, argv++) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
getlines(fp, &b); getlines(fp, &b);
fclose(fp); fclose(fp);
} }
@ -59,7 +64,7 @@ main(int argc, char *argv[])
for(l = 0; l < b.nlines; ++l) { for(l = 0; l < b.nlines; ++l) {
fputs(b.lines[l], stdout); fputs(b.lines[l], stdout);
} }
return EXIT_SUCCESS; return 0;
} }
if(!(space = malloc(maxlen + 2))) if(!(space = malloc(maxlen + 2)))
@ -78,6 +83,6 @@ main(int argc, char *argv[])
fputs("\n", stdout); fputs("\n", stdout);
} }
return EXIT_SUCCESS; return 0;
} }

38
mkdir.c
View File

@ -10,26 +10,35 @@
static void mkdirp(char *); static void mkdirp(char *);
static void
usage(void)
{
eprintf("usage: %s [-p] directory...\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
bool pflag = false; bool pflag = false;
char c;
while((c = getopt(argc, argv, "p")) != -1) ARGBEGIN {
switch(c) { case 'p':
case 'p': pflag = true;
pflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
for(; argc > 0; argc--, argv++) {
if(pflag) {
mkdirp(argv[0]);
} else if(mkdir(argv[0], S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
eprintf("mkdir %s:", argv[0]);
} }
for(; optind < argc; optind++) }
if(pflag)
mkdirp(argv[optind]); return 0;
else if(mkdir(argv[optind], S_IRWXU|S_IRWXG|S_IRWXO) == -1)
eprintf("mkdir %s:", argv[optind]);
return EXIT_SUCCESS;
} }
void void
@ -46,3 +55,4 @@ mkdirp(char *path)
*p = '/'; *p = '/';
} while(p); } while(p);
} }

View File

@ -5,13 +5,26 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s name...\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
while(getopt(argc, argv, "") != -1) ARGBEGIN {
exit(EXIT_FAILURE); default:
for(; optind < argc; optind++) usage();
if(mkfifo(argv[optind], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == -1) } ARGEND;
eprintf("mkfifo %s:", argv[optind]); for(; argc > 0; argc--, argv++) {
return EXIT_SUCCESS; if(mkfifo(argv[0], S_IRUSR|S_IWUSR|S_IRGRP|\
S_IWGRP|S_IROTH|S_IWOTH) == -1) {
eprintf("mkfifo %s:", argv[0]);
}
}
return 0;
} }

27
mv.c
View File

@ -9,26 +9,36 @@
int mv(const char *, const char *); int mv(const char *, const char *);
static void
usage(void)
{
eprintf("usage: %s source... dest\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct stat st; struct stat st;
if(getopt(argc, argv, "") != -1) ARGBEGIN {
exit(EXIT_FAILURE); default:
usage();
} ARGEND;
if(argc > 3 && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode))) if(argc > 3 && !(stat(argv[argc-1], &st) == 0 && S_ISDIR(st.st_mode)))
eprintf("%s: not a directory\n", argv[argc-1]); eprintf("%s: not a directory\n", argv[argc-1]);
enmasse(argc - optind, &argv[optind], mv); enmasse(argc, &argv[0], mv);
return EXIT_SUCCESS;
return 0;
} }
int int
mv (const char *s1, const char *s2) mv(const char *s1, const char *s2)
{ {
if (rename(s1, s2) == 0) if (rename(s1, s2) == 0)
return 0; return 0;
if (errno == EXDEV) if (errno == EXDEV) {
{
cp_rflag = true; cp_rflag = true;
rm_rflag = true; rm_rflag = true;
cp(s1, s2); cp(s1, s2);
@ -37,3 +47,4 @@ mv (const char *s1, const char *s2)
} }
return -1; return -1;
} }

69
nl.c
View File

@ -14,39 +14,50 @@ static const char *sep = "\t";
static long incr = 1; static long incr = 1;
static regex_t preg; static regex_t preg;
static void
usage(void)
{
eprintf("usage: %s [-b style] [-i increment] [-s sep] [FILE...]\n",
argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
FILE *fp; FILE *fp;
char *r;
while((c = getopt(argc, argv, "b:i:s:")) != -1) ARGBEGIN {
switch(c) { case 'b':
case 'b': r = EARGF(usage());
mode = optarg[0]; mode = r[0];
if(optarg[0] == 'p') if(r[0] == 'p') {
regcomp(&preg, &optarg[1], REG_NOSUB); regcomp(&preg, &r[1], REG_NOSUB);
else if(!strchr("ant", optarg[0]) || optarg[1] != '\0') } else if(!strchr("ant", mode)) {
eprintf("usage: %s [-b mode] [-i increment] [-s separator] [file...]\n", argv[0]); usage();
break;
case 'i':
incr = estrtol(optarg, 0);
break;
case 's':
sep = optarg;
break;
default:
exit(2);
} }
if(optind == argc) break;
case 'i':
incr = estrtol(EARGF(usage()), 0);
break;
case 's':
sep = EARGF(usage());
break;
default:
usage();
} ARGEND;
if(argc == 0) {
nl(stdin); nl(stdin);
else for(; optind < argc; optind++) { } else for(; argc > 0; argc--, argv++) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
nl(fp); nl(fp);
fclose(fp); fclose(fp);
} }
return EXIT_SUCCESS;
return 0;
} }
void void
@ -56,12 +67,16 @@ nl(FILE *fp)
long n = 0; long n = 0;
size_t size = 0; size_t size = 0;
while(afgets(&buf, &size, fp)) while(afgets(&buf, &size, fp)) {
if((mode == 'a') if((mode == 'a')
|| (mode == 'p' && !regexec(&preg, buf, 0, NULL, 0)) || (mode == 'p'
|| (mode == 't' && buf[0] != '\n')) && !regexec(&preg, buf, 0, NULL, 0))
|| (mode == 't' && buf[0] != '\n')) {
printf("%6ld%s%s", n += incr, sep, buf); printf("%6ld%s%s", n += incr, sep, buf);
else } else {
printf(" %s", buf); printf(" %s", buf);
}
}
free(buf); free(buf);
} }

29
nohup.c
View File

@ -9,21 +9,34 @@
enum { Error = 127, Found = 126 }; enum { Error = 127, Found = 126 };
static void
usage(void)
{
eprintf("usage: %s command [argument...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int fd; int fd;
if(getopt(argc, argv, "") != -1) ARGBEGIN {
exit(Error); default:
if(optind == argc) usage();
enprintf(Error, "usage: %s command [argument...]\n", argv[0]); } ARGEND;
if(argc == 0)
usage();
if(signal(SIGHUP, SIG_IGN) == SIG_ERR) if(signal(SIGHUP, SIG_IGN) == SIG_ERR)
enprintf(Error, "signal HUP:"); enprintf(Error, "signal HUP:");
if(isatty(STDOUT_FILENO)) { if(isatty(STDOUT_FILENO)) {
if((fd = open("nohup.out", O_APPEND|O_CREAT, S_IRUSR|S_IWUSR)) == -1) if((fd = open("nohup.out", O_APPEND|O_CREAT,
S_IRUSR|S_IWUSR)) == -1) {
enprintf(Error, "open nohup.out:"); enprintf(Error, "open nohup.out:");
}
if(dup2(fd, STDOUT_FILENO) == -1) if(dup2(fd, STDOUT_FILENO) == -1)
enprintf(Error, "dup2:"); enprintf(Error, "dup2:");
close(fd); close(fd);
@ -32,7 +45,9 @@ main(int argc, char *argv[])
if(dup2(STDOUT_FILENO, STDERR_FILENO) == -1) if(dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
enprintf(Error, "dup2:"); enprintf(Error, "dup2:");
execvp(argv[optind], &argv[optind]); execvp(argv[0], &argv[0]);
enprintf(errno == ENOENT ? Error : Found, "exec %s:", argv[optind]); enprintf(errno == ENOENT ? Error : Found, "exec %s:", argv[0]);
return Error; return Error;
} }

60
paste.c
View File

@ -13,42 +13,44 @@ typedef struct {
const char *name; const char *name;
} Fdescr; } Fdescr;
static void eusage(void);
static size_t unescape(wchar_t *); static size_t unescape(wchar_t *);
static wint_t in(Fdescr *); static wint_t in(Fdescr *);
static void out(wchar_t); static void out(wchar_t);
static void sequential(Fdescr *, int, const wchar_t *, size_t); static void sequential(Fdescr *, int, const wchar_t *, size_t);
static void parallel(Fdescr *, int, const wchar_t *, size_t); static void parallel(Fdescr *, int, const wchar_t *, size_t);
static void
usage(void)
{
eprintf("usage: %s [-s] [-d list] file...\n", argv0);
exit(1);
}
int int
main(int argc, char **argv) { main(int argc, char *argv[])
{
const char *adelim = NULL; const char *adelim = NULL;
bool seq = false; bool seq = false;
wchar_t *delim; wchar_t *delim;
size_t len; size_t len;
Fdescr *dsc; Fdescr *dsc;
int i, c; int i;
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
while((c = getopt(argc, argv, "sd:")) != -1) ARGBEGIN {
switch(c) { case 's':
case 's': seq = true;
seq = true; break;
break; case 'd':
case 'd': adelim = EARGF(usage());
adelim = optarg; break;
break; default:
case '?': usage();
default: } ARGEND;
eusage();
break;
}
argc -= optind;
argv += optind;
if(argc == 0) if(argc == 0)
eusage(); usage();
/* populate delimeters */ /* populate delimeters */
if(!adelim) if(!adelim)
@ -98,16 +100,14 @@ main(int argc, char **argv) {
free(delim); free(delim);
free(dsc); free(dsc);
return 0; return 0;
} }
static void
eusage(void) {
eprintf("usage: paste [-s][-d list] file...\n");
}
static size_t static size_t
unescape(wchar_t *delim) { unescape(wchar_t *delim)
{
wchar_t c; wchar_t c;
size_t i; size_t i;
size_t len; size_t len;
@ -140,7 +140,8 @@ unescape(wchar_t *delim) {
} }
static wint_t static wint_t
in(Fdescr *f) { in(Fdescr *f)
{
wint_t c = fgetwc(f->fp); wint_t c = fgetwc(f->fp);
if(c == WEOF && ferror(f->fp)) if(c == WEOF && ferror(f->fp))
@ -150,14 +151,16 @@ in(Fdescr *f) {
} }
static void static void
out(wchar_t c) { out(wchar_t c)
{
putwchar(c); putwchar(c);
if(ferror(stdout)) if(ferror(stdout))
eprintf("write error:"); eprintf("write error:");
} }
static void static void
sequential(Fdescr *dsc, int len, const wchar_t *delim, size_t cnt) { sequential(Fdescr *dsc, int len, const wchar_t *delim, size_t cnt)
{
int i; int i;
for(i = 0; i < len; i++) { for(i = 0; i < len; i++) {
@ -185,7 +188,8 @@ sequential(Fdescr *dsc, int len, const wchar_t *delim, size_t cnt) {
} }
static void static void
parallel(Fdescr *dsc, int len, const wchar_t *delim, size_t cnt) { parallel(Fdescr *dsc, int len, const wchar_t *delim, size_t cnt)
{
int last; int last;
do { do {

31
pwd.c
View File

@ -7,24 +7,32 @@
static const char *getpwd(const char *cwd); static const char *getpwd(const char *cwd);
static void
usage(void)
{
eprintf("usage: %s [-LP]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *cwd, c; char *cwd;
char mode = 'L'; char mode = 'L';
while((c = getopt(argc, argv, "LP")) != -1) ARGBEGIN {
switch(c) { case 'L':
case 'L': case 'P':
case 'P': mode = ARGC();
mode = c; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
cwd = agetcwd(); cwd = agetcwd();
puts((mode == 'L') ? getpwd(cwd) : cwd); puts((mode == 'L') ? getpwd(cwd) : cwd);
return EXIT_SUCCESS;
return 0;
} }
const char * const char *
@ -42,3 +50,4 @@ getpwd(const char *cwd)
else else
return cwd; return cwd;
} }

36
rm.c
View File

@ -7,23 +7,29 @@
#include "fs.h" #include "fs.h"
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-fr] FILE...\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c; ARGBEGIN {
case 'f':
rm_fflag = true;
break;
case 'r':
rm_rflag = true;
break;
default:
usage();
} ARGEND;
for(; argc > 0; argc--, argv++)
rm(argv[0]);
while((c = getopt(argc, argv, "fr")) != -1) return 0;
switch(c) {
case 'f':
rm_fflag = true;
break;
case 'r':
rm_rflag = true;
break;
default:
exit(EXIT_FAILURE);
}
for(; optind < argc; optind++)
rm(argv[optind]);
return EXIT_SUCCESS;
} }

76
seq.c
View File

@ -11,43 +11,56 @@ static int digitsright(const char *);
static double estrtod(const char *); static double estrtod(const char *);
static bool validfmt(const char *); static bool validfmt(const char *);
static void
usage(void)
{
eprintf("usage: %s [-f format] [-s sep] [-w width] first"
" [inc [last]]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
const char *starts = "1", *steps = "1", *ends = "1", *sep = "\n"; const char *starts = "1", *steps = "1", *ends = "1", *sep = "\n";
bool wflag = false; bool wflag = false;
char c, ftmp[BUFSIZ], *fmt = ftmp; char ftmp[BUFSIZ], *fmt = ftmp;
double start, step, end, out, dir; double start, step, end, out, dir;
while((c = getopt(argc, argv, "f:s:w")) != -1) ARGBEGIN {
switch(c) { case 'f':
case 'f': if(!validfmt(EARGF(usage())))
if(!validfmt(optarg)) eprintf("%s: invalid format\n", ARGF());
eprintf("%s: invalid format\n", optarg); fmt = ARGF();
fmt = optarg;
break;
case 's':
sep = optarg;
break;
case 'w':
wflag = true;
break;
}
switch(argc-optind) {
case 3:
starts = argv[optind++];
steps = argv[optind++];
ends = argv[optind++];
break; break;
case 2: case 's':
starts = argv[optind++]; sep = EARGF(usage());
/* fallthrough */ break;
case 1: case 'w':
ends = argv[optind++]; wflag = true;
break; break;
default: default:
eprintf("usage: %s [-w] [-f fmt] [-s separator] [start [step]] end\n", argv[0]); usage();
} ARGEND;
switch(argc) {
case 3:
starts = argv[0];
argv++;
steps = argv[0];
argv++;
ends = argv[0];
argv++;
break;
case 2:
starts = argv[0];
argv++;
/* fallthrough */
case 1:
ends = argv[0];
break;
default:
usage();
} }
start = estrtod(starts); start = estrtod(starts);
step = estrtod(steps); step = estrtod(steps);
@ -65,9 +78,9 @@ main(int argc, char *argv[])
if(wflag) { if(wflag) {
int left = MAX(digitsleft(starts), digitsleft(ends)); int left = MAX(digitsleft(starts), digitsleft(ends));
snprintf(ftmp, sizeof ftmp, "%%0%d.%df", right+left+(right != 0), right); snprintf(ftmp, sizeof ftmp, "%%0%d.%df",
} right+left+(right != 0), right);
else } else
snprintf(ftmp, sizeof ftmp, "%%.%df", right); snprintf(ftmp, sizeof ftmp, "%%.%df", right);
} }
for(out = start; out * dir <= end * dir; out += step) { for(out = start; out * dir <= end * dir; out += step) {
@ -77,7 +90,7 @@ main(int argc, char *argv[])
} }
printf("\n"); printf("\n");
return EXIT_SUCCESS; return 0;
} }
int int
@ -155,3 +168,4 @@ format:
return false; return false;
} }
} }

23
sleep.c
View File

@ -3,18 +3,29 @@
#include <unistd.h> #include <unistd.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s seconds\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
unsigned int seconds; unsigned int seconds;
if(getopt(argc, argv, "") != -1) ARGBEGIN {
exit(EXIT_FAILURE); default:
if(optind != argc-1) usage();
eprintf("usage: %s seconds\n", argv[0]); } ARGEND;
seconds = estrtol(argv[optind], 0); if(argc < 1)
usage();
seconds = estrtol(argv[0], 0);
while((seconds = sleep(seconds)) > 0) while((seconds = sleep(seconds)) > 0)
; ;
return EXIT_SUCCESS; return 0;
} }

52
sort.c
View File

@ -14,38 +14,49 @@ static bool uflag = false;
static struct linebuf linebuf = EMPTY_LINEBUF; static struct linebuf linebuf = EMPTY_LINEBUF;
static void
usage(void)
{
eprintf("usage: %s [-ru] [file...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
long i; long i;
FILE *fp; FILE *fp;
while((c = getopt(argc, argv, "ru")) != -1) ARGBEGIN {
switch(c) { case 'r':
case 'r': rflag = true;
rflag = true; break;
break; case 'u':
case 'u': uflag = true;
uflag = true; break;
break; default:
default: usage();
exit(2); } ARGEND;
}
if(optind == argc) if(argc == 0) {
getlines(stdin, &linebuf); getlines(stdin, &linebuf);
else for(; optind < argc; optind++) { } else for(; argc > 0; argc--, argv++) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
getlines(fp, &linebuf); getlines(fp, &linebuf);
fclose(fp); fclose(fp);
} }
qsort(linebuf.lines, linebuf.nlines, sizeof *linebuf.lines, (int (*)(const void *, const void *))linecmp); qsort(linebuf.lines, linebuf.nlines, sizeof *linebuf.lines,
(int (*)(const void *, const void *))linecmp);
for(i = 0; i < linebuf.nlines; i++) for(i = 0; i < linebuf.nlines; i++) {
if(!uflag || i == 0 || strcmp(linebuf.lines[i], linebuf.lines[i-1]) != 0) if(!uflag || i == 0 || strcmp(linebuf.lines[i],
linebuf.lines[i-1]) != 0) {
fputs(linebuf.lines[i], stdout); fputs(linebuf.lines[i], stdout);
return EXIT_SUCCESS; }
}
return 0;
} }
int int
@ -53,3 +64,4 @@ linecmp(const char **a, const char **b)
{ {
return strcmp(*a, *b) * (rflag ? -1 : +1); return strcmp(*a, *b) * (rflag ? -1 : +1);
} }

45
tail.c
View File

@ -9,36 +9,40 @@
static void dropinit(FILE *, const char *, long); static void dropinit(FILE *, const char *, long);
static void taketail(FILE *, const char *, long); static void taketail(FILE *, const char *, long);
static void
usage(void)
{
eprintf("usage: %s [-n lines] [file]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
long n = 10; long n = 10;
FILE *fp; FILE *fp;
void (*tail)(FILE *, const char *, long) = taketail; void (*tail)(FILE *, const char *, long) = taketail;
while((c = getopt(argc, argv, "n:")) != -1) ARGBEGIN {
switch(c) { case 'n':
case 'n': n = abs(estrtol(EARGF(usage()), 0));
n = abs(estrtol(optarg, 0)); if(optarg[0] == '+')
if(optarg[0] == '+') tail = dropinit;
tail = dropinit; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
} if(argc == 0) {
if(optind == argc)
tail(stdin, "<stdin>", n); tail(stdin, "<stdin>", n);
else if(optind == argc-1) { } else if(argc == 1) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
tail(fp, argv[optind], n); tail(fp, argv[0], n);
fclose(fp); fclose(fp);
} } else
else usage();
eprintf("usage: %s [-n lines] [file]\n", argv[0]);
return EXIT_SUCCESS; return 0;
} }
void void
@ -76,3 +80,4 @@ taketail(FILE *fp, const char *str, long n)
free(ring); free(ring);
free(size); free(size);
} }

41
tee.c
View File

@ -5,38 +5,49 @@
#include <unistd.h> #include <unistd.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-a] [file...]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
bool aflag = false; bool aflag = false;
char buf[BUFSIZ], c; char buf[BUFSIZ];
int i, nfps = 1; int i, nfps = 1;
size_t n; size_t n;
FILE **fps; FILE **fps;
while((c = getopt(argc, argv, "a")) != -1) ARGBEGIN {
switch(c) { case 'a':
case 'a': aflag = true;
aflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
if(!(fps = malloc(sizeof *fps))) if(!(fps = malloc(sizeof *fps)))
eprintf("malloc:"); eprintf("malloc:");
fps[nfps-1] = stdout; fps[nfps-1] = stdout;
for(; optind < argc; optind++) { for(; argc > 0; argc--, argv++) {
if(!(fps = realloc(fps, ++nfps * sizeof *fps))) if(!(fps = realloc(fps, ++nfps * sizeof *fps)))
eprintf("realloc:"); eprintf("realloc:");
if(!(fps[nfps-1] = fopen(argv[optind], aflag ? "a" : "w"))) if(!(fps[nfps-1] = fopen(argv[0], aflag ? "a" : "w")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
} }
while((n = fread(buf, 1, sizeof buf, stdin)) > 0) while((n = fread(buf, 1, sizeof buf, stdin)) > 0) {
for(i = 0; i < nfps; i++) for(i = 0; i < nfps; i++) {
if(fwrite(buf, 1, n, fps[i]) != n) if(fwrite(buf, 1, n, fps[i]) != n)
eprintf("%s: write error:", buf); eprintf("%s: write error:", buf);
}
}
if(ferror(stdin)) if(ferror(stdin))
eprintf("<stdin>: read error:"); eprintf("<stdin>: read error:");
return EXIT_SUCCESS;
return 0;
} }

39
touch.c
View File

@ -14,26 +14,32 @@ static void touch(const char *);
static bool cflag = false; static bool cflag = false;
static time_t t; static time_t t;
static void
usage(void)
{
eprintf("usage: %s [-c] [-t stamp] file...\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char c;
t = time(NULL); t = time(NULL);
while((c = getopt(argc, argv, "ct:")) != -1)
switch(c) { ARGBEGIN {
case 'c': case 'c':
cflag = true; cflag = true;
break; break;
case 't': case 't':
t = estrtol(optarg, 0); t = estrtol(EARGF(usage()), 0);
break; break;
default: default:
exit(EXIT_FAILURE); usage();
} } ARGEND;
for(; optind < argc; optind++) for(; argc > 0; argc--, argv++)
touch(argv[optind]); touch(argv[0]);
return EXIT_SUCCESS;
return 0;
} }
void void
@ -60,3 +66,4 @@ touch(const char *str)
close(fd); close(fd);
touch(str); touch(str);
} }

57
uname.c
View File

@ -6,6 +6,13 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include "util.h" #include "util.h"
static void
usage(void)
{
eprintf("usage: %s [-amnrsv]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -14,32 +21,30 @@ main(int argc, char *argv[])
bool rflag = false; bool rflag = false;
bool sflag = false; bool sflag = false;
bool vflag = false; bool vflag = false;
char c;
struct utsname u; struct utsname u;
while((c = getopt(argc, argv, "amnrsv")) != -1) ARGBEGIN {
switch(c) { case 'a':
case 'a': mflag = nflag = rflag = sflag = vflag = true;
mflag = nflag = rflag = sflag = vflag = true; break;
break; case 'm':
case 'm': mflag = true;
mflag = true; break;
break; case 'n':
case 'n': nflag = true;
nflag = true; break;
break; case 'r':
case 'r': rflag = true;
rflag = true; break;
break; case 's':
case 's': sflag = true;
sflag = true; break;
break; case 'v':
case 'v': vflag = true;
vflag = true; break;
break; default:
default: usage();
exit(EXIT_FAILURE); } ARGEND;
}
if(uname(&u) == -1) if(uname(&u) == -1)
eprintf("uname:"); eprintf("uname:");
@ -54,5 +59,7 @@ main(int argc, char *argv[])
if(mflag) if(mflag)
putword(u.machine); putword(u.machine);
putchar('\n'); putchar('\n');
return EXIT_SUCCESS;
return 0;
} }

50
uniq.c
View File

@ -19,39 +19,44 @@ static bool uflag = false;
static char *prev_line = NULL; static char *prev_line = NULL;
static long prev_line_count = 0; static long prev_line_count = 0;
static void
usage(void)
{
eprintf("usage: %s [-cdu] [input]]\n", argv0);
exit(1);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int c;
FILE *fp; FILE *fp;
while((c = getopt(argc, argv, "cdu")) != -1) ARGBEGIN {
switch(c) { case 'c':
case 'c': countfmt = "%7ld ";
countfmt = "%7ld "; break;
break; case 'd':
case 'd': dflag = true;
dflag = true; break;
break; case 'u':
case 'u': uflag = true;
uflag = true; break;
break; default:
default: usage();
exit(2); } ARGEND;
}
if(optind == argc) if(argc == 0) {
uniq(stdin, "<stdin>"); uniq(stdin, "<stdin>");
else if(optind == argc - 1) { } else if(argc == 1) {
if(!(fp = fopen(argv[optind], "r"))) if(!(fp = fopen(argv[0], "r")))
eprintf("fopen %s:", argv[optind]); eprintf("fopen %s:", argv[0]);
uniq(fp, argv[optind]); uniq(fp, argv[0]);
fclose(fp); fclose(fp);
} else } else
enprintf(2, "too many arguments\n"); usage();
uniq_finish(); uniq_finish();
return EXIT_SUCCESS; return 0;
} }
void void
@ -96,3 +101,4 @@ uniq_finish()
{ {
uniq_line(NULL); uniq_line(NULL);
} }