source: tools/repeat.c@ 5eba8ce

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 5eba8ce was 5eba8ce, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

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