1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#define _GNU_SOURCE /* getopt_long */
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define VERSION "1.0.0"
void
print_usage(FILE *output)
{
fprintf(output, "Usage:\n");
fprintf(output, "rpt [-n | --count COUNT] [-f | --force] COMMAND\n");
fprintf(output, "rpt [-h | --help]\n");
fprintf(output, "rpt [-V | --version]\n");
}
void
print_help()
{
puts("Repeat : repeat a shell command");
puts("");
print_usage(stdout);
}
void
print_version()
{
puts(VERSION);
}
/* Exit whenever a subprocess fails. */
void
exit_on_error(int status)
{
if (!status)
return;
fprintf(stderr, "Process exited with status %d, aborting.\n", status);
exit(1);
}
/* Ignore subprocesses' errors. */
void
continue_on_error(int status)
{
(void) status;
}
int
main(int argc, char* argv[])
{
struct option const opts[] = {
{"count", required_argument, NULL, 'n'},
{"force", no_argument, NULL, 'f'},
{"version", no_argument, NULL, 'V'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
opterr = 0; /* dismiss getopt error message */
int opt;
char *strcount = NULL;
long count = 1;
void (*handle_exit_f)(int status) = exit_on_error;
while ((opt = getopt_long(argc, argv, "+:n:fVh", opts, NULL)) >= 0)
{
switch(opt)
{
case 'n':
strcount = optarg;
break;
case 'f':
handle_exit_f = continue_on_error;
break;
case 'h':
print_help();
return 0;
case 'V':
print_version();
return 0;
case ':':
fprintf(stderr, "COUNT value missing.\n");
print_usage(stderr);
return 1;
default:
print_usage(stderr);
return 1;
}
}
if (strcount)
{
char *err = NULL;
count = strtol(strcount, &err, 10);
if (err && (*err != '\0'))
{
fprintf(stderr, "Failed to read COUNT : '%s'.\n",
strcount);
return 2;
}
}
return 0;
}
|