source: tools/repeat.c@ a85e44c

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since a85e44c was 4149d9d, checked in by Thierry Delisle <tdelisle@…>, 8 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.