source: tools/repeat.c @ 0bdd8d2a

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 0bdd8d2a was 4149d9d, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

replacing old repeat script with c program

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <stdbool.h>
5#include <string.h>
6
7#include <getopt.h>
8#include <unistd.h>
9
10#include <sys/types.h>
11#include <sys/wait.h>
12
13int repetitions = 0;
14bool stop_on_error = false;
15char * this_cmd = NULL;
16bool print_iterations = false;
17
18void parse_args(int argc, char * argv[]);
19void setup();
20int run();
21
22int main(int argc, char * argv[]) {
23        parse_args(argc, argv);
24        setup();
25        for(int i = 0; i < repetitions; i++) {
26                if(print_iterations) {
27                        printf("\r%d / %d", i, repetitions);
28                }
29                int retcode = run();
30                if( !WIFEXITED(retcode) ) {
31                        printf("FAILURE: %d @ %d\n", retcode, i + 1);
32                }
33                if( !WIFEXITED(retcode) && stop_on_error ) {
34                        return retcode;
35                }
36        }
37
38        if(print_iterations) {
39                printf("\r%d / %d\n", repetitions, repetitions);
40        }
41
42        return 0;
43}
44
45void usage( FILE * out, int code ) {
46        fprintf(out, "%s [OPTION] [--] N CMD\n", this_cmd);
47        fprintf(out, "Repeat CMD N times\n\n");
48        fprintf(out, "\t-h,--help\tprint this usage message\n");
49        fprintf(out, "\t-s\tstop on error\n");
50        fprintf(out, "\t-i\toutput iterations instead of CMD stdout\n");
51        fprintf(out, "\t-x\tprint CMD before running it\n");
52        exit(code);
53}
54
55char ** cmd_to_run = NULL;
56bool print_cmd = false;
57pid_t child_pid = 0;
58
59void error() {
60        fprintf(stderr,"\n");
61        usage(stderr, 1);
62}
63
64void parse_args(int argc, char * argv[]) {
65        this_cmd = argv[0];
66
67        enum { Help, };
68        static struct option long_opts[] = {
69                { "help", no_argument, 0, Help },
70                { 0, 0, 0, 0 }
71        }; // long_opts
72        int long_index;
73
74        int c;
75        while ( (c = getopt_long( argc, argv, "hsxi", long_opts, &long_index)) != -1 ) {
76                switch ( c ) {
77                        case Help:
78                        case 'h':
79                                usage(stdout, 0);
80                                break;
81                        case 's':
82                                stop_on_error = true;
83                                break;
84                        case 'x':
85                                print_cmd = true;
86                                break;
87                        case 'i':
88                                print_iterations = true;
89                                break;
90                        default:
91                                error("");
92                                break;
93                } // switch
94        } // while
95
96        if( argc < optind + 2 ) {
97                fprintf(stderr, "Too few arguments\n");
98                error();
99        }
100
101        char * pEnd;
102        char * repeats_c = argv[optind];
103        repetitions = strtol(repeats_c, &pEnd, 10);
104
105        bool is_number = (size_t)(pEnd - repeats_c) == strlen(repeats_c);
106        bool in_range  = repetitions > 0;
107        if( !is_number || !in_range ) {
108                fprintf(
109                        stderr,
110                        "repetitions option : %s not an number greater than 0\n",
111                        repeats_c
112                );
113                error();
114        }
115
116        cmd_to_run = argv + optind + 1;
117}
118
119void setup() {
120
121}
122
123int run() {
124        /* Duplicate this process. */
125        child_pid = fork();
126        if (child_pid != 0) {
127
128                /* This is the parent process. */
129                int status;
130                waitpid(child_pid, &status, 0);
131                child_pid = 0;
132                return status;
133        }
134        else {
135                /* Now execute PROGRAM, searching for it in the path.  */
136                if( print_cmd ) {
137                        char ** cmd = cmd_to_run;
138                        while (*cmd) {
139                                printf("%s ", *cmd);
140                                cmd++;
141                        }
142                        printf("\n");
143                }
144                if(print_iterations) {
145                        __attribute__((unused)) FILE * ignore =
146                                freopen("/dev/null", "w", stdout);
147                }
148                execvp ( *cmd_to_run, cmd_to_run);
149                /* The execvp  function returns only if an error occurs.  */
150                fprintf(stderr, "an error occurred in execvp\n");
151                abort ();
152        }
153
154        return 0;
155}
Note: See TracBrowser for help on using the repository browser.