Subversion Repositories DevTools

Rev

Rev 5742 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5742 Rev 5847
Line 53... Line 53...
53
 
53
 
54
/*
54
/*
55
**  Globals
55
**  Globals
56
*/
56
*/
57
 
57
 
58
HANDLE hJobObject;
58
HANDLE          hJobObject;             // Job to contain the child process
59
DWORD dwThreadIdTimer;
-
 
60
HANDLE hThreadTimer;
-
 
61
DWORD   dwChildExitCode;
59
DWORD           dwChildExitCode;        // Child process exit code
62
unsigned int timeOut = 10;                   // Seconds
60
unsigned int    timeOut = 10;           // Seconds
63
 
61
 
64
/*
62
/*
65
**  Prototypes (forward declarations)
63
**  Prototypes (forward declarations)
66
*/
64
*/
67
VOID ErrorExit(LPTSTR);
65
VOID ErrorExit(LPTSTR);
68
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) ;
66
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) ;
69
DWORD WINAPI ThreadTimer( LPVOID lpParam );
-
 
70
BOOL WINAPI KillJob(DWORD dwCtrlType);
67
BOOL WINAPI KillJob(DWORD dwCtrlType);
71
unsigned int parseDuration(const char* str);
68
unsigned int parseDuration(const char* str);
72
 
69
 
73
/*----------------------------------------------------------------------------
70
/*----------------------------------------------------------------------------
74
** FUNCTION           : main
71
** FUNCTION           : main
75
**
72
**
76
** DESCRIPTION        : Mainentry point
73
** DESCRIPTION        : Main entry point
-
 
74
**                      timeout [-time:nnn] program ......
77
**
75
**
78
**
76
**
79
** INPUTS             : argc            - Number of args
77
** INPUTS             : argc            - Number of args
80
**                      argv            - Address of args
78
**                      argv            - Address of args
81
**
79
**
82
** RETURNS            :
80
** RETURNS            : 0   - Program exited OK
-
 
81
**                      ... - Program exit code
-
 
82
**                      124 - Timeout
-
 
83
**                      125 - Internal error
-
 
84
**                      126 - Could not find program
-
 
85
**                      127 - Could not create Job
83
**
86
**
84
----------------------------------------------------------------------------*/
87
----------------------------------------------------------------------------*/
85
 
88
 
86
int main(int argc, char *argv[])
89
int main(int argc, char *argv[])
87
{
90
{
Line 185... Line 188...
185
    if ( !SetConsoleCtrlHandler( KillJob, TRUE)) {
188
    if ( !SetConsoleCtrlHandler( KillJob, TRUE)) {
186
        ErrorExitMsg(EXIT_CANCELED, "SetConsoleCtrlHandler");
189
        ErrorExitMsg(EXIT_CANCELED, "SetConsoleCtrlHandler");
187
    }
190
    }
188
  
191
  
189
    /*
192
    /*
190
    **  Now create the child process.
193
    **  Create the child process.
191
    */
194
    */
192
    SetEnvironmentVariable( "GBE_JOBDEBUG", "CreateChild" );
195
    SetEnvironmentVariable( "GBE_JOBDEBUG", "CreateChild" );
193
    PROCESS_INFORMATION piProcInfo;
196
    PROCESS_INFORMATION piProcInfo;
194
    
197
    
195
    /*
198
    /*
Line 222... Line 225...
222
        TerminateProcess(piProcInfo.hProcess, 101);
225
        TerminateProcess(piProcInfo.hProcess, 101);
223
        ErrorExitMsg(EXIT_ENOENT, "AssignProcessToJobObject");
226
        ErrorExitMsg(EXIT_ENOENT, "AssignProcessToJobObject");
224
    };
227
    };
225
 
228
 
226
    /*
229
    /*
227
    **  Create a thread to timeout the main process
-
 
228
    */
-
 
229
    SetEnvironmentVariable( "GBE_JOBDEBUG", "CreateThread" );
-
 
230
    hThreadTimer = CreateThread(
-
 
231
        NULL,                        // default security attributes 
-
 
232
        0,                           // use default stack size  
-
 
233
        ThreadTimer,                 // thread function
-
 
234
        NULL,                        // argument to thread function
-
 
235
        0,                           // use default creation flags 
-
 
236
        &dwThreadIdTimer);           // returns the thread identifier
-
 
237
 
-
 
238
    if (hThreadTimer == NULL)
-
 
239
        ErrorExitMsg(EXIT_CANCELED, "Create Timer Thread");
-
 
240
 
-
 
241
    /*
-
 
242
    **  Start(Resume) the master thread for the comamnd
230
    **  Start(Resume) the master thread for the comamnd
243
    **  What for the process to complete
231
    **  What for the process to complete
244
    */
232
    */
245
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ResumeChild" );
233
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ResumeChild" );
246
    if (ResumeThread (piProcInfo.hThread) == -1 ){
234
    if (ResumeThread (piProcInfo.hThread) == -1 ){
247
         ErrorExitMsg(EXIT_ENOENT, "ResumeThread - did not resume");
235
         ErrorExitMsg(EXIT_ENOENT, "ResumeThread - did not resume");
248
    }
236
    }
249
 
237
 
250
    SetEnvironmentVariable( "GBE_JOBDEBUG", "WaitChild" );
-
 
251
    WaitForSingleObject( piProcInfo.hProcess, INFINITE );
-
 
252
    
-
 
253
    /*
238
    /*
254
    ** When the one process I started terminates, then kill the entire JOB
239
    ** Body of the wating process
255
    */
240
    */
256
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ChildDone" );
241
    SetEnvironmentVariable( "GBE_JOBDEBUG", "WaitChild" );
-
 
242
    {
-
 
243
        char lBuf[30];
-
 
244
        unsigned int secs;
-
 
245
        DWORD dwWaitResult;
-
 
246
        bool  bChildDone = false;
-
 
247
 
-
 
248
        _snprintf(lBuf, sizeof(lBuf), "%u", timeOut);
-
 
249
        SetEnvironmentVariable( "GBE_JOBLIMIT", lBuf );
-
 
250
 
-
 
251
        /*
-
 
252
        ** Wait for the Job to complete, one second at a time 
-
 
253
        ** This allows us to indicate progress via an EnvVar 
-
 
254
        */
-
 
255
        for (secs = timeOut; secs > 0; secs--) 
-
 
256
        { 
-
 
257
            /*
-
 
258
            ** Update ENV with time remaining
-
 
259
            ** Simply for diagnostic purposes
-
 
260
            */
-
 
261
            _snprintf(lBuf, sizeof(lBuf), "%u", secs);
-
 
262
            SetEnvironmentVariable( "GBE_JOBTIME", lBuf );
-
 
263
 
-
 
264
            /*
-
 
265
            **  Wait one second
-
 
266
            */
-
 
267
            dwWaitResult  = WaitForSingleObject( piProcInfo.hProcess, 1000 );
-
 
268
            switch (dwWaitResult) 
-
 
269
            {
-
 
270
                /* 
-
 
271
                **  Event object was signaled
-
 
272
                **      The process has completed 
-
 
273
                */ 
-
 
274
                case WAIT_OBJECT_0: 
-
 
275
                    SetEnvironmentVariable( "GBE_JOBDEBUG", "ChildDone" );
257
    TerminateThread(hThreadTimer, 0);
276
                    bChildDone = true;
-
 
277
                    break;
-
 
278
                    
-
 
279
                /* 
-
 
280
                **  Timeout
-
 
281
                **      Update EnvVar and do again 
-
 
282
                */ 
-
 
283
                case WAIT_TIMEOUT:
-
 
284
                    break;
-
 
285
 
-
 
286
                /* 
-
 
287
                **  An error occurred 
-
 
288
                */ 
-
 
289
                default: 
-
 
290
                    ErrorExitMsg(EXIT_CANCELED, "WaitForSingleObject");
-
 
291
                    break;
-
 
292
            }
-
 
293
        }
-
 
294
 
-
 
295
        /*
-
 
296
        ** Timer loop complete 
-
 
297
        ** May be a timeout or the Child has completed 
-
 
298
        */
-
 
299
        if (!bChildDone)
-
 
300
        {
-
 
301
            /*
-
 
302
            ** Timeout 
-
 
303
            **  Terminate the Job 
-
 
304
            */
-
 
305
            fprintf(stderr, "Process exceeded time limit (%u Secs)\n", timeOut); 
-
 
306
            fflush(stderr) ;
-
 
307
 
-
 
308
            SetEnvironmentVariable( "GBE_JOBDEBUG", "TimeOut" );
-
 
309
            TerminateJobObject(hJobObject, EXIT_TIMEDOUT);
-
 
310
        }
-
 
311
    }
-
 
312
    
-
 
313
    SetEnvironmentVariable( "GBE_JOBDEBUG", "TimerDone" );
258
    TerminateJobObject(hJobObject, 100);
314
    TerminateJobObject(hJobObject, 100);
259
 
315
 
260
    /*
316
    /*
261
    **  Determine the exist status of the child process
317
    **  Determine the exist status of the child process
262
    */
318
    */
-
 
319
    SetEnvironmentVariable( "GBE_JOBDEBUG", "GetChildExitCode" );
263
    if (!GetExitCodeProcess( piProcInfo.hProcess, &dwChildExitCode ))
320
    if (!GetExitCodeProcess( piProcInfo.hProcess, &dwChildExitCode ))
264
        ErrorExit("Error getting child exist code");
321
        ErrorExit("Error getting child exist code");
265
 
322
 
266
    /*
323
    /*
267
    **  Exit with the childs exit code
324
    **  Exit with the childs exit code
-
 
325
    **      Have tried to use ExitProcess, but it hangs from time to time
268
    */
326
    */
269
    SetEnvironmentVariable( "GBE_JOBDEBUG", "Exit" );
327
    SetEnvironmentVariable( "GBE_JOBDEBUG", "Exit" );
270
    ExitProcess(dwChildExitCode);
328
    ExitProcess(dwChildExitCode);
271
 
329
 
272
    /*
330
    /*
273
    ** Should not happen
331
    ** Should not happen
274
    */
332
    */
275
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ExitReturn" );
333
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ExitReturn" );
276
    return EXIT_FAILURE;
334
    return EXIT_CANCELED;
277
}
335
}
278
 
336
 
279
/*----------------------------------------------------------------------------
337
/*----------------------------------------------------------------------------
280
** FUNCTION           : apply_time_suffix
338
** FUNCTION           : apply_time_suffix
281
**
339
**
Line 389... Line 447...
389
**
447
**
390
----------------------------------------------------------------------------*/
448
----------------------------------------------------------------------------*/
391
 
449
 
392
VOID ErrorExit (LPTSTR lpszMessage)
450
VOID ErrorExit (LPTSTR lpszMessage)
393
{ 
451
{ 
-
 
452
   SetEnvironmentVariable( "GBE_JOBDEBUG", lpszMessage );
394
   fprintf(stderr, "%s\n", lpszMessage);
453
   fprintf(stderr, "%s\n", lpszMessage);
395
   fflush(stderr) ;
454
   fflush(stderr) ;
396
   ExitProcess(EXIT_CANCELED);
455
   ExitProcess(EXIT_CANCELED);
397
}
456
}
398
 
457
 
399
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) 
458
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) 
400
{ 
459
{ 
401
    // Retrieve the system error message for the last-error code
460
    // Retrieve the system error message for the last-error code
402
 
461
 
403
    LPVOID lpMsgBuf;
462
    LPVOID lpMsgBuf;
404
    DWORD dw = GetLastError(); 
463
    DWORD dw = GetLastError();
-
 
464
    char msgBuf[300]; 
405
 
465
 
406
    FormatMessage(
466
    FormatMessage(
407
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
467
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
408
        FORMAT_MESSAGE_FROM_SYSTEM |
468
        FORMAT_MESSAGE_FROM_SYSTEM |
409
        FORMAT_MESSAGE_IGNORE_INSERTS,
469
        FORMAT_MESSAGE_IGNORE_INSERTS,
Line 413... Line 473...
413
        (LPTSTR) &lpMsgBuf,
473
        (LPTSTR) &lpMsgBuf,
414
        0, NULL );
474
        0, NULL );
415
 
475
 
416
    // Display the error message and exit the process
476
    // Display the error message and exit the process
417
 
477
 
418
    fprintf(stderr, "%s failed with error %d: %s\n", lpszFunction, dw, lpMsgBuf);
478
    _snprintf(msgBuf, sizeof(msgBuf),  "%s failed with error %d: %s\n", lpszFunction, dw, lpMsgBuf);
-
 
479
    SetEnvironmentVariable( "GBE_JOBDEBUG", msgBuf );
-
 
480
    fprintf(stderr, msgBuf);
419
    fflush(stderr) ;
481
    fflush(stderr) ;
420
    LocalFree(lpMsgBuf);
482
    LocalFree(lpMsgBuf);
421
 
483
 
422
    ExitProcess(ecode); 
484
    ExitProcess(ecode); 
423
}
485
}