Subversion Repositories DevTools

Rev

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

Rev 5741 Rev 5742
Line 53... Line 53...
53
 
53
 
54
/*
54
/*
55
**  Globals
55
**  Globals
56
*/
56
*/
57
 
57
 
58
CRITICAL_SECTION CriticalSection;
-
 
59
HANDLE hJobObject;
58
HANDLE hJobObject;
60
DWORD dwThreadIdTimer;
59
DWORD dwThreadIdTimer;
61
HANDLE hThreadTimer;
60
HANDLE hThreadTimer;
62
DWORD   dwChildExitCode;
61
DWORD   dwChildExitCode;
63
HANDLE  hChildProcess;
-
 
64
unsigned int timeOut = 10;                   // Seconds
62
unsigned int timeOut = 10;                   // Seconds
65
 
63
 
66
/*
64
/*
67
**  Prototypes (forward declarations)
65
**  Prototypes (forward declarations)
68
*/
66
*/
69
HANDLE CreateChildProcess(LPTSTR);
-
 
70
VOID ErrorExit(LPTSTR);
67
VOID ErrorExit(LPTSTR);
71
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) ;
68
void ErrorExitMsg(UINT ecode, LPTSTR lpszFunction) ;
72
DWORD WINAPI ThreadTimer( LPVOID lpParam );
69
DWORD WINAPI ThreadTimer( LPVOID lpParam );
73
BOOL WINAPI KillJob(DWORD dwCtrlType);
70
BOOL WINAPI KillJob(DWORD dwCtrlType);
74
unsigned int parseDuration(const char* str);
71
unsigned int parseDuration(const char* str);
Line 86... Line 83...
86
**
83
**
87
----------------------------------------------------------------------------*/
84
----------------------------------------------------------------------------*/
88
 
85
 
89
int main(int argc, char *argv[])
86
int main(int argc, char *argv[])
90
{
87
{
91
   SECURITY_ATTRIBUTES saAttr; 
-
 
92
   LPTSTR   command;
88
   LPTSTR   command;
93
   int      argp;
89
   int      argp;
94
 
90
 
95
    /*
91
    /*
96
    **  Process command line arguments
92
    **  Process command line arguments
Line 169... Line 165...
169
            ErrorExitMsg(EXIT_CANCELED, "CreateJobObject");
165
            ErrorExitMsg(EXIT_CANCELED, "CreateJobObject");
170
 
166
 
171
    /*
167
    /*
172
    **  Set extended information to allow job breakaway
168
    **  Set extended information to allow job breakaway
173
    **  Required so that we can have a timeout job within a timeout job
169
    **  Required so that we can have a timeout job within a timeout job
-
 
170
    **  Note: Not sure this works to well on all systems (Windows-7)
174
    */
171
    */
175
//  JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimits = {0, 0, JOB_OBJECT_LIMIT_BREAKAWAY_OK};
-
 
176
//  JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimits = {basicLimits};
-
 
177
//  if (!SetInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &extendedLimits, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)))
-
 
178
//      ErrorExitMsg(EXIT_CANCELED, "Error setting job object information.");
-
 
179
 
-
 
180
     JOBOBJECT_EXTENDED_LIMIT_INFORMATION JBLI;
172
     JOBOBJECT_EXTENDED_LIMIT_INFORMATION JBLI;
181
     if(!QueryInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &JBLI, sizeof(JBLI), NULL)){
173
     if(!QueryInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &JBLI, sizeof(JBLI), NULL)){
182
        ErrorExitMsg(EXIT_CANCELED, "QueryInformationJobObject");
174
        ErrorExitMsg(EXIT_CANCELED, "QueryInformationJobObject");
183
     }
175
     }
184
 
176
 
Line 188... Line 180...
188
     }
180
     }
189
 
181
 
190
    /*
182
    /*
191
    ** Register a handler for control-C
183
    ** Register a handler for control-C
192
    */
184
    */
193
    if ( !SetConsoleCtrlHandler( KillJob, TRUE))
185
    if ( !SetConsoleCtrlHandler( KillJob, TRUE)) {
194
    {
-
 
195
        ErrorExitMsg(EXIT_CANCELED, "SetConsoleCtrlHandler");
186
        ErrorExitMsg(EXIT_CANCELED, "SetConsoleCtrlHandler");
196
    }
187
    }
197
  
188
  
198
 
-
 
199
    /*
-
 
200
    **  Create a security attribute
-
 
201
    **  Set the bInheritHandle flag so pipe handles are inherited
-
 
202
    */
-
 
203
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
-
 
204
    saAttr.bInheritHandle = TRUE; 
-
 
205
    saAttr.lpSecurityDescriptor = NULL; 
-
 
206
 
-
 
207
    /*
189
    /*
208
    **  Now create the child process.
190
    **  Now create the child process.
209
    */
191
    */
-
 
192
    SetEnvironmentVariable( "GBE_JOBDEBUG", "CreateChild" );
210
   PROCESS_INFORMATION piProcInfo; 
193
    PROCESS_INFORMATION piProcInfo;
211
   STARTUPINFO siStartInfo; 
-
 
212
 
194
    
213
   fprintf(stderr, "CreateChildProcess: %s\n",command);
-
 
214
   fflush(stderr) ;
-
 
215
 
-
 
216
    /*
195
    /*
217
    **  Set up members of STARTUPINFO structure.
196
    **  Set up members of STARTUPINFO structure.
218
    */
197
    */
-
 
198
    STARTUPINFO siStartInfo; 
219
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
199
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
220
    siStartInfo.cb = sizeof(STARTUPINFO);
200
    siStartInfo.cb = sizeof(STARTUPINFO);
221
 
201
 
222
    /*
202
    /*
223
    **  Create the child process.
203
    **  Create the child process.
Line 236... Line 216...
236
            &piProcInfo                 // receives PROCESS_INFORMATION
216
            &piProcInfo                 // receives PROCESS_INFORMATION
237
            )) {
217
            )) {
238
        ErrorExitMsg(EXIT_CANNOT_INVOKE,"CreateChildProcess");
218
        ErrorExitMsg(EXIT_CANNOT_INVOKE,"CreateChildProcess");
239
    }
219
    }
240
 
220
 
241
    hChildProcess = piProcInfo.hProcess;
-
 
242
 
-
 
243
    if (!AssignProcessToJobObject(hJobObject, hChildProcess)) {
221
    if (!AssignProcessToJobObject(hJobObject, piProcInfo.hProcess)) {
244
        TerminateProcess(hChildProcess, 101);
222
        TerminateProcess(piProcInfo.hProcess, 101);
245
        ErrorExitMsg(EXIT_ENOENT, "AssignProcessToJobObject");
223
        ErrorExitMsg(EXIT_ENOENT, "AssignProcessToJobObject");
246
    };
224
    };
247
 
225
 
248
    if (ResumeThread (piProcInfo.hThread) == -1 ){
-
 
249
         ErrorExitMsg(EXIT_ENOENT, "ResumeThread - did not resume");
-
 
250
    }
-
 
251
 
-
 
252
    /*
-
 
253
    **  Create a critical section to be used by pipe writers
-
 
254
    */
-
 
255
    InitializeCriticalSection(&CriticalSection);
-
 
256
 
-
 
257
    /*
226
    /*
258
    **  Create a thread to timeout the main process
227
    **  Create a thread to timeout the main process
259
    */
228
    */
-
 
229
    SetEnvironmentVariable( "GBE_JOBDEBUG", "CreateThread" );
260
    hThreadTimer = CreateThread(
230
    hThreadTimer = CreateThread(
261
        NULL,                        // default security attributes 
231
        NULL,                        // default security attributes 
262
        0,                           // use default stack size  
232
        0,                           // use default stack size  
263
        ThreadTimer,                 // thread function
233
        ThreadTimer,                 // thread function
264
        NULL,                        // argument to thread function
234
        NULL,                        // argument to thread function
Line 267... Line 237...
267
 
237
 
268
    if (hThreadTimer == NULL)
238
    if (hThreadTimer == NULL)
269
        ErrorExitMsg(EXIT_CANCELED, "Create Timer Thread");
239
        ErrorExitMsg(EXIT_CANCELED, "Create Timer Thread");
270
 
240
 
271
    /*
241
    /*
-
 
242
    **  Start(Resume) the master thread for the comamnd
272
    **  What for the process to complete
243
    **  What for the process to complete
273
    */
244
    */
-
 
245
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ResumeChild" );
-
 
246
    if (ResumeThread (piProcInfo.hThread) == -1 ){
-
 
247
         ErrorExitMsg(EXIT_ENOENT, "ResumeThread - did not resume");
-
 
248
    }
-
 
249
 
-
 
250
    SetEnvironmentVariable( "GBE_JOBDEBUG", "WaitChild" );
274
    WaitForSingleObject( hChildProcess, INFINITE );
251
    WaitForSingleObject( piProcInfo.hProcess, INFINITE );
275
    
252
    
276
    /*
253
    /*
277
    ** If the one process I started terminates, then kill the entire JOB
254
    ** When the one process I started terminates, then kill the entire JOB
278
    */
255
    */
-
 
256
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ChildDone" );
279
    TerminateThread(hThreadTimer, 0);
257
    TerminateThread(hThreadTimer, 0);
280
    TerminateJobObject(hJobObject, 100);
258
    TerminateJobObject(hJobObject, 100);
281
    
-
 
282
 
259
 
283
    /*
260
    /*
284
    **  Determine the exist status of the child process
261
    **  Determine the exist status of the child process
285
    */
262
    */
286
    if (!GetExitCodeProcess( hChildProcess, &dwChildExitCode ))
263
    if (!GetExitCodeProcess( piProcInfo.hProcess, &dwChildExitCode ))
287
        ErrorExit("Error getting child exist code");
264
        ErrorExit("Error getting child exist code");
288
 
265
 
289
    /*
266
    /*
290
    **  Release resources used by the critical section object.
-
 
291
    */
-
 
292
    DeleteCriticalSection(&CriticalSection);
-
 
293
 
-
 
294
    /*
-
 
295
    **  Exist with the childs exist code
267
    **  Exit with the childs exit code
296
    */
268
    */
-
 
269
    SetEnvironmentVariable( "GBE_JOBDEBUG", "Exit" );
297
    ExitProcess(dwChildExitCode);
270
    ExitProcess(dwChildExitCode);
298
 
271
 
299
    /*
272
    /*
300
    ** Should not happen
273
    ** Should not happen
301
    */
274
    */
-
 
275
    SetEnvironmentVariable( "GBE_JOBDEBUG", "ExitReturn" );
302
    return EXIT_FAILURE;
276
    return EXIT_FAILURE;
303
}
277
}
304
 
278
 
305
/*----------------------------------------------------------------------------
279
/*----------------------------------------------------------------------------
306
** FUNCTION           : apply_time_suffix
280
** FUNCTION           : apply_time_suffix
Line 399... Line 373...
399
 
373
 
400
  return intDuration;
374
  return intDuration;
401
}
375
}
402
 
376
 
403
/*----------------------------------------------------------------------------
377
/*----------------------------------------------------------------------------
404
** FUNCTION           : CreateChildProcess
-
 
405
**
-
 
406
** DESCRIPTION        : Create the child process
-
 
407
**                      It will be created in its own process group , so that all members
-
 
408
**                      of the same process can be killed.
-
 
409
**
-
 
410
** INPUTS             : command         - Command string
-
 
411
**
-
 
412
** RETURNS            : False if can't create
-
 
413
**
-
 
414
----------------------------------------------------------------------------*/
-
 
415
 
-
 
416
HANDLE CreateChildProcess( LPTSTR command)
-
 
417
{ 
-
 
418
   PROCESS_INFORMATION piProcInfo; 
-
 
419
   STARTUPINFO siStartInfo; 
-
 
420
 
-
 
421
   fprintf(stderr, "CreateChildProcess: %s\n",command);
-
 
422
   fflush(stderr) ;
-
 
423
 
-
 
424
    /*
-
 
425
    **  Set up members of STARTUPINFO structure.
-
 
426
    */
-
 
427
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
-
 
428
    siStartInfo.cb = sizeof(STARTUPINFO);
-
 
429
 
-
 
430
    /*
-
 
431
    **  Create the child process.
-
 
432
    */
-
 
433
    //#define LOCAL_CREATE_BREAKAWAY_FROM_JOB 0x01000000
-
 
434
    //#define CREATION_FLAGS LOCAL_CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP 
-
 
435
    #define CREATION_FLAGS CREATE_NEW_PROCESS_GROUP | CREATE_SUSPENDED
-
 
436
    if (! CreateProcess(
-
 
437
            NULL,                       // Use from command line
-
 
438
            command,                    // command line
-
 
439
            NULL,                       // process security attributes
-
 
440
            NULL,                       // primary thread security attributes 
-
 
441
            TRUE,                       // handles are inherited 
-
 
442
            CREATION_FLAGS ,            // creation flags 
-
 
443
            NULL,                       // use parent's environment 
-
 
444
            NULL,                       // use parent's current directory 
-
 
445
            &siStartInfo,               // STARTUPINFO pointer 
-
 
446
            &piProcInfo                 // receives PROCESS_INFORMATION
-
 
447
            )) return (NULL);
-
 
448
 
-
 
449
    return piProcInfo.hProcess;
-
 
450
}
-
 
451
 
-
 
452
 
-
 
453
/*----------------------------------------------------------------------------
-
 
454
** FUNCTION           : ErrorExit
378
** FUNCTION           : ErrorExit
455
**                      ErrorExitMsg - report system messae
379
**                      ErrorExitMsg - report system messae
456
**
380
**
457
** DESCRIPTION        : Error processing
381
** DESCRIPTION        : Error processing
458
**                      REport an error and terminate process
382
**                      REport an error and terminate process