@@ -55,13 +55,18 @@ typedef struct
55
55
time_t last_heartbeat ; /**< Time when the last heartbeat was received from the application. */
56
56
} Application_t ;
57
57
58
+ typedef struct
59
+ {
60
+ int app_count ; /**< Total number of applications found in the ini file. */
61
+ int udp_port ; /**< UDP port number specified in the ini file. */
62
+ char ini_file [MAX_APP_CMD_LENGTH ]; /**< Path to the ini file. */
63
+ time_t ini_last_modified_time ; /**< Last modified time of the ini file. */
64
+ time_t uptime ; /**< System uptime in seconds. */
65
+ int ini_index ; /**< Index used to read an array in the ini file. */
66
+ } AppState_t ;
67
+
58
68
static Application_t apps [MAX_APPS ]; /**< Array of Application_t structures representing applications defined in the ini file. */
59
- static int app_count ; /**< Total number of applications found in the ini file. */
60
- static int udp_port = 12345 ; /**< UDP port number specified in the ini file. */
61
- static char ini_file [MAX_APP_CMD_LENGTH ] = INI_FILE ; /**< Path to the ini file. */
62
- static time_t ini_last_modified_time ; /**< Last modified time of the ini file. */
63
- static long uptime ; /**< System uptime in seconds. */
64
- static int ini_index ; /**< Index used to read an array in the ini file. */
69
+ static AppState_t app_state = {0 };
65
70
66
71
//------------------------------------------------------------------
67
72
@@ -89,7 +94,7 @@ void update_heartbeat_time(int i)
89
94
90
95
int find_pid (int pid )
91
96
{
92
- for (int i = 0 ; i < app_count ; i ++ )
97
+ for (int i = 0 ; i < app_state . app_count ; i ++ )
93
98
{
94
99
if (0 < apps [i ].pid && pid == apps [i ].pid )
95
100
{
@@ -137,157 +142,195 @@ bool get_first_heartbeat(int i)
137
142
138
143
//------------------------------------------------------------------
139
144
140
- int set_ini_file (char * path )
145
+ static time_t file_modified_time (char * path )
146
+ {
147
+ struct stat attr ;
148
+ stat (path , & attr );
149
+ return attr .st_mtime ;
150
+ }
151
+
152
+ bool is_ini_updated ()
141
153
{
142
- int ret = 1 ; // fail
143
- int length = strlen (path );
154
+ time_t file_last_modified_time = file_modified_time (app_state .ini_file );
155
+ return (file_last_modified_time != app_state .ini_last_modified_time );
156
+ }
144
157
145
- if (NULL != path && 0 < length && MAX_APP_CMD_LENGTH > length )
158
+ static int check_ini_file (char * path )
159
+ {
160
+ if (!path || strlen (path ) == 0 || strlen (path ) >= MAX_APP_CMD_LENGTH )
146
161
{
147
- if (f_exist (path ))
148
- {
149
- strncpy (ini_file , path , MAX_APP_CMD_LENGTH );
150
- LOGD ("ini file has been set to %s" , ini_file );
151
- ret = 0 ; // success
152
- }
162
+ return 1 ;
153
163
}
154
164
155
- if (ret )
165
+ if (! f_exist ( path ) )
156
166
{
157
- LOGE ( "Error setting ini file %s" , path ) ;
167
+ return 1 ;
158
168
}
159
169
160
- return ret ;
170
+ return 0 ;
161
171
}
162
172
163
- static time_t file_modified_time (char * path )
173
+ int set_ini_file (char * path )
164
174
{
165
- struct stat attr ;
166
- stat (path , & attr );
167
- return attr .st_mtime ;
168
- }
175
+ if (check_ini_file (path ))
176
+ {
177
+ LOGE ("Invalid path" );
178
+ return 1 ;
179
+ }
169
180
170
- bool is_ini_updated ()
171
- {
172
- time_t file_last_modified_time = file_modified_time (ini_file );
173
- return (file_last_modified_time != ini_last_modified_time );
181
+ snprintf (app_state .ini_file , MAX_APP_CMD_LENGTH , "%s" , path );
182
+ LOGD ("INI file set to: %s" , app_state .ini_file );
183
+ return 0 ;
174
184
}
175
185
176
186
static int handler (void * user , const char * section , const char * name , const char * value )
177
187
{
178
188
(void )(user );
179
- const char * _section = "processWatchdog" ;
180
- char b [INI_MAX_LINE ];
181
- #define MATCH (s , n ) strcmp(section, s) == 0 && strcmp(name, n) == 0
182
- #define SECTION (n , s ) snprintf(b, sizeof(b) - 1, "%d_%s", n + 1, s);
189
+ const char * target_section = "processWatchdog" ;
190
+ char expected_name [INI_MAX_LINE ];
183
191
184
- if (MATCH ( _section , "udp_port" ) )
192
+ if (strcmp ( section , target_section ) != 0 )
185
193
{
186
- udp_port = atoi ( value ) ;
194
+ return 1 ;
187
195
}
188
196
189
- if (MATCH (_section , "n_apps" ))
197
+ // Global parameters
198
+ if (strcmp (name , "udp_port" ) == 0 )
190
199
{
191
- app_count = atoi (value );
200
+ if (!parse_int (value , 1 , 65535 , & app_state .udp_port ))
201
+ {
202
+ LOGE ("Invalid UDP port: %s" , value );
203
+ return 0 ;
204
+ }
205
+
206
+ return 1 ;
192
207
}
193
208
194
- if (app_count > 0 )
209
+ if (strcmp ( name , "n_apps" ) == 0 )
195
210
{
196
- SECTION (ini_index , "name" );
197
-
198
- if (MATCH (_section , b ))
211
+ if (!parse_int (value , 0 , MAX_APPS , & app_state .app_count ))
199
212
{
200
- int length = strlen (value );
213
+ LOGE ("Invalid n_apps: %s" , value );
214
+ return 0 ;
215
+ }
201
216
202
- if (length > MAX_APP_NAME_LENGTH )
203
- {
204
- LOGE ("NAME is longer than %d" , MAX_APP_NAME_LENGTH );
205
- }
217
+ return 1 ;
218
+ }
206
219
207
- length = length > MAX_APP_NAME_LENGTH ? MAX_APP_NAME_LENGTH : length ;
208
- strncpy (apps [ini_index ].name , value , length );
209
- }
220
+ // Application parameters
221
+ int index = app_state .ini_index ;
210
222
211
- SECTION (ini_index , "start_delay" );
223
+ if (index >= app_state .app_count )
224
+ {
225
+ return 1 ;
226
+ }
212
227
213
- if (MATCH (_section , b ))
214
- {
215
- apps [ini_index ].start_delay = atoi (value );
216
- }
228
+ #define GEN_NAME (field ) snprintf(expected_name, sizeof(expected_name), "%d_%s", index + 1, field)
217
229
218
- SECTION (ini_index , "heartbeat_delay" );
230
+ if (GEN_NAME ("name" ), strcmp (name , expected_name ) == 0 )
231
+ {
232
+ snprintf (apps [index ].name , MAX_APP_NAME_LENGTH , "%s" , value );
219
233
220
- if (MATCH ( _section , b ) )
234
+ if (strlen ( value ) >= MAX_APP_NAME_LENGTH )
221
235
{
222
- apps [ ini_index ]. heartbeat_delay = atoi ( value );
236
+ LOGW ( "App %d name truncated" , index );
223
237
}
224
-
225
- SECTION ( ini_index , "heartbeat_interval" );
226
-
227
- if (MATCH ( _section , b ))
238
+ }
239
+ else if ( GEN_NAME ( "start_delay" ), strcmp ( name , expected_name ) == 0 )
240
+ {
241
+ if (! parse_int ( value , 0 , INT_MAX , & apps [ index ]. start_delay ))
228
242
{
229
- apps [ini_index ].heartbeat_interval = atoi (value );
243
+ LOGE ("Invalid start_delay for app %d: %s" , index , value );
244
+ return 0 ;
230
245
}
231
-
232
- SECTION ( ini_index , "cmd" ); // this always must be the last one
233
-
234
- if (MATCH ( _section , b ))
246
+ }
247
+ else if ( GEN_NAME ( "heartbeat_delay" ), strcmp ( name , expected_name ) == 0 )
248
+ {
249
+ if (! parse_int ( value , 0 , INT_MAX , & apps [ index ]. heartbeat_delay ))
235
250
{
236
- int length = strlen (value );
237
-
238
- if (length > MAX_APP_CMD_LENGTH )
239
- {
240
- LOGE ("CMD is longer than %d" , MAX_APP_CMD_LENGTH );
241
- }
251
+ LOGE ("Invalid heartbeat_delay for app %d: %s" , index , value );
252
+ return 0 ;
253
+ }
254
+ }
255
+ else if (GEN_NAME ("heartbeat_interval" ), strcmp (name , expected_name ) == 0 )
256
+ {
257
+ if (!parse_int (value , 0 , INT_MAX , & apps [index ].heartbeat_interval ))
258
+ {
259
+ LOGE ("Invalid heartbeat_interval for app %d: %s" , index , value );
260
+ return 0 ;
261
+ }
262
+ }
263
+ else if (GEN_NAME ("cmd" ), strcmp (name , expected_name ) == 0 ) // this always must be the last one
264
+ {
265
+ snprintf (apps [index ].cmd , MAX_APP_CMD_LENGTH , "%s" , value );
242
266
243
- length = length > MAX_APP_CMD_LENGTH ? MAX_APP_CMD_LENGTH : length ;
244
- strncpy (apps [ini_index ].cmd , value , length );
245
- ini_index ++ ; // order of the names in the ini are important
267
+ if (strlen (value ) >= MAX_APP_CMD_LENGTH )
268
+ {
269
+ LOGE ("Invalid cmd for app %d - longer than %d charachters" , index , MAX_APP_CMD_LENGTH );
270
+ return 0 ;
246
271
}
272
+
273
+ app_state .ini_index ++ ; // Move to next app after processing cmd
247
274
}
248
275
249
276
return 1 ;
250
277
}
251
278
252
279
int read_ini_file ()
253
280
{
254
- uptime = get_uptime ();
255
- LOGD ("Reading ini file %s" , ini_file );
256
281
memset (apps , 0 , sizeof (apps ));
257
- app_count = 0 ;
258
- ini_index = 0 ;
282
+ app_state .ini_index = 0 ;
283
+ app_state .app_count = 0 ;
284
+ app_state .uptime = get_uptime ();
285
+ app_state .udp_port = UDP_PORT ;
259
286
260
- if (ini_parse (ini_file , handler , NULL ) < 0 )
287
+ // ini_file could have already set by set_ini_file() earlier
288
+ if (check_ini_file (app_state .ini_file ))
261
289
{
262
- LOGE ("Can't load %s" , ini_file );
290
+ LOGD ("Using default ini file %s" , INI_FILE );
291
+ set_ini_file (INI_FILE );
292
+ }
293
+
294
+ LOGD ("Reading ini file %s" , app_state .ini_file );
295
+
296
+ if (ini_parse (app_state .ini_file , handler , NULL ) < 0 )
297
+ {
298
+ LOGE ("Failed to parse INI file %s" , app_state .ini_file );
263
299
return 1 ;
264
300
}
265
301
266
- LOGD ("%d processes have found in the ini file %s" , app_count , ini_file );
267
- ini_last_modified_time = file_modified_time (ini_file );
302
+ if (app_state .ini_index != app_state .app_count )
303
+ {
304
+ LOGW ("Config mismatch: Expected %d apps, found %d" , app_state .app_count , app_state .ini_index );
305
+ }
306
+
307
+ LOGD ("%d processes have found in the ini file %s" , app_state .app_count , app_state .ini_file );
308
+ app_state .ini_last_modified_time = file_modified_time (app_state .ini_file );
268
309
return 0 ;
269
310
}
270
311
271
312
//------------------------------------------------------------------
272
313
273
314
bool is_application_running (int i )
274
315
{
275
- if (apps [i ].pid > 0 )
316
+ if (apps [i ].pid <= 0 )
276
317
{
277
- // Check if the application is running on Linux
278
- if (kill (apps [i ].pid , 0 ) == 0 )
279
- {
280
- return true; // Process is running
281
- }
282
- else if (errno == EPERM )
283
- {
284
- LOGE ("No permission to check if process %s is running : %s" , apps [i ].name , strerror (errno ));
285
- return true;
286
- }
287
- else
288
- {
289
- LOGD ("Process %s is not running : %s" , apps [i ].name , strerror (errno ));
290
- }
318
+ return false;
319
+ }
320
+
321
+ // Check if the application is running
322
+ if (kill (apps [i ].pid , 0 ) == 0 )
323
+ {
324
+ return true; // Process is running
325
+ }
326
+ else if (errno == EPERM )
327
+ {
328
+ LOGE ("No permission to check if process %s is running : %s" , apps [i ].name , strerror (errno ));
329
+ return true;
330
+ }
331
+ else
332
+ {
333
+ LOGD ("Process %s is not running : %s" , apps [i ].name , strerror (errno ));
291
334
}
292
335
293
336
return false;
@@ -300,7 +343,7 @@ bool is_application_started(int i)
300
343
301
344
bool is_application_start_time (int i )
302
345
{
303
- return (get_uptime () - uptime ) >= (long )apps [i ].start_delay ;
346
+ return (get_uptime () - app_state . uptime ) >= (long )apps [i ].start_delay ;
304
347
}
305
348
306
349
void start_application (int i )
@@ -347,6 +390,11 @@ void kill_application(int i)
347
390
bool killed = false;
348
391
LOGD ("Killing process %s" , apps [i ].name );
349
392
393
+ if (apps [i ].pid <= 0 )
394
+ {
395
+ return ;
396
+ }
397
+
350
398
if (kill (apps [i ].pid , SIGTERM ) < 0 && errno != ESRCH )
351
399
{
352
400
LOGE ("Failed to terminate process %s, error: %d - %s" , apps [i ].name , errno , strerror (errno ));
@@ -474,7 +522,7 @@ void restart_application(int i)
474
522
475
523
int get_app_count (void )
476
524
{
477
- return app_count ;
525
+ return app_state . app_count ;
478
526
}
479
527
480
528
char * get_app_name (int i )
@@ -484,5 +532,5 @@ char *get_app_name(int i)
484
532
485
533
int get_udp_port (void )
486
534
{
487
- return udp_port ;
535
+ return app_state . udp_port ;
488
536
}
0 commit comments