commiting initial code which works
[runfinite.git] / src / main.cpp
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include <unistd.h>
6
7 #include <sys/wait.h>
8 #include <sys/types.h>
9
10
11
12 #define ERR_WRONGARGS -1
13 #define ERR_EXECVE -2
14 #define ERR_FORK -3
15 #define ERR_WAITPID -4
16 #define ERR_KILL -5
17
18
19
20 void printUsage(FILE* out, int argc, char** argv)
21 {
22 fprintf(out, "Run command <command> for at least a specific time. Kill\n");
23 fprintf(out, "process executing <command> if time is over. \n");
24 fprintf(out, "\n");
25 fprintf(out, "Usage: %s [options] <command>\n", argv[0]);
26 fprintf(out, "\n");
27 fprintf(out, "Options:\n");
28 fprintf(out, " -h Print this help.\n");
29 fprintf(out, " -t <sec> Number of seconds.\n");
30 fprintf(out, " -v Be verbose.\n");
31 }
32
33
34 int main(int argc, char** argv)
35 {
36 bool argHelp=false;
37 bool argTime=false;
38 bool argVerbose=false;
39 float maxtime=0;
40
41 //Wrong arguments
42 if( argc<=1 )
43 {
44 printUsage(stderr, argc, argv);
45 return ERR_WRONGARGS;
46 }
47
48
49 //Get the argument index of the head of <command>
50 int fiarg=1;
51
52 //Aha, argument -- skip it
53 while( fiarg<argc && strncmp(argv[fiarg], "-", 1)==0 )
54 {
55 //Help option
56 if( strncmp(argv[fiarg], "-h", 2) == 0 )
57 {
58 argHelp = true;
59 }
60
61 //Parse time
62 else if( strncmp(argv[fiarg], "-t", 2) == 0 )
63 {
64 //Time is given -- goto next argument
65 argTime=true;
66 fiarg++;
67 if( fiarg >= argc)
68 {
69 fprintf(stderr, "Missing time.\n");
70 fprintf(stderr, "\n");
71 printUsage(stderr, argc, argv);
72 return ERR_WRONGARGS;
73 }
74
75 //Convert the time given in seconds to float
76 char* endptr;
77 maxtime = strtof( argv[fiarg], &endptr);
78 if( endptr != argv[fiarg] + strlen(argv[fiarg]) ||
79 maxtime<0.0)
80 {
81 fprintf(stderr, "Invalid time.\n");
82 fprintf(stderr, "\n");
83 printUsage(stderr, argc, argv);
84 return ERR_WRONGARGS;
85 }
86 }
87
88 //Help option
89 else if( strncmp(argv[fiarg], "-v", 2) == 0 )
90 {
91 argVerbose = true;
92 }
93
94
95 //Unknown option
96 else
97 {
98 fprintf(stderr, "Invalid argument: %s\n", argv[fiarg]);
99 fprintf(stderr, "\n");
100 printUsage(stderr, argc, argv);
101 return ERR_WRONGARGS;
102 }
103
104 //Goto next argument
105 fiarg++;
106 }
107
108
109 //Print help
110 if( argHelp )
111 {
112 printUsage(stdout, argc, argv);
113 return 0;
114 }
115
116
117 //No time given...
118 if( !argTime )
119 {
120 fprintf(stderr, "No time given!\n");
121 fprintf(stderr, "\n");
122 printUsage(stderr, argc, argv);
123 return ERR_WRONGARGS;
124 }
125
126 //No command left
127 if( fiarg>=argc )
128 {
129 fprintf(stderr, "No command given!\n");
130 fprintf(stderr, "\n");
131 printUsage(stderr, argc, argv);
132 return ERR_WRONGARGS;
133 }
134
135
136
137 //Fork process
138 pid_t pid = fork();
139
140
141 //Childrens code...
142 if( pid == 0)
143 {
144 char** newargv = (char**) malloc( sizeof(char*)*(argc-fiarg+1) );
145 char* newenv[] = {NULL};
146
147 //Copy arguments
148 for( int i=fiarg; i<argc; i++)
149 {
150 newargv[i-fiarg] = (char*)malloc(strlen(argv[i])+1);
151 strcpy(newargv[i-fiarg], argv[i]);
152 }
153 newargv[argc-fiarg] = NULL;
154
155
156 //Execute child process
157 execve(newargv[0], newargv, newenv);
158 perror("execve");
159 return ERR_EXECVE;
160 }
161 //Parents code...
162 else
163 {
164 //Failure
165 if(pid==-1)
166 {
167 perror("fork");
168 return ERR_FORK;
169 }
170
171
172 //Nmb of loops=seconds
173 float loops=0;
174 //Status flags of child process
175 int status, w;
176
177 do
178 {
179 //Kill the child
180 if( loops >= maxtime )
181 {
182 if( argVerbose )
183 printf("Kill child...\n");
184
185 if( kill(pid, SIGTERM ) < 0)
186 break;
187 }
188
189 //Sleep a round
190 sleep(1);
191 loops++;
192
193 //Test for child
194 if( waitpid(-1, &status, WNOHANG | WUNTRACED | WCONTINUED) < 0 )
195 break;
196
197 }while( !WIFEXITED(status) );
198 }
199
200
201 if( argVerbose)
202 printf("Finished\n");
203
204 return 0;
205 }
206
207