14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
|
*/
#include "config.h"
#include <errno.h>
#include <string.h>
#import "OFProcess.h"
#import "OFSubprocess.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFDictionary.h"
#import "OFLocale.h"
#import "OFString.h"
#import "OFSystemInfo.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFWriteFailedException.h"
#include <windows.h>
@interface OFProcess ()
@interface OFSubprocess ()
- (of_char16_t *)of_wideEnvironmentForDictionary: (OFDictionary *)dictionary;
- (char *)of_environmentForDictionary: (OFDictionary *)environment;
@end
@implementation OFProcess
+ (instancetype)processWithProgram: (OFString *)program
@implementation OFSubprocess
+ (instancetype)subprocessWithProgram: (OFString *)program
{
return [[[self alloc] initWithProgram: program] autorelease];
}
+ (instancetype)processWithProgram: (OFString *)program
arguments: (OFArray *)arguments
+ (instancetype)subprocessWithProgram: (OFString *)program
arguments: (OFArray *)arguments
{
return [[[self alloc] initWithProgram: program
arguments: arguments] autorelease];
}
+ (instancetype)processWithProgram: (OFString *)program
programName: (OFString *)programName
arguments: (OFArray *)arguments
+ (instancetype)subprocessWithProgram: (OFString *)program
programName: (OFString *)programName
arguments: (OFArray *)arguments
{
return [[[self alloc] initWithProgram: program
programName: programName
arguments: arguments] autorelease];
}
+ (instancetype)processWithProgram: (OFString *)program
programName: (OFString *)programName
arguments: (OFArray *)arguments
environment: (OFDictionary *)environment
+ (instancetype)subprocessWithProgram: (OFString *)program
programName: (OFString *)programName
arguments: (OFArray *)arguments
environment: (OFDictionary *)environment
{
return [[[self alloc] initWithProgram: program
programName: programName
arguments: arguments
environment: environment] autorelease];
}
|
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
-
+
|
@try {
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
void *pool;
OFMutableString *argumentsString;
_process = INVALID_HANDLE_VALUE;
_handle = INVALID_HANDLE_VALUE;
_readPipe[0] = _writePipe[1] = NULL;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0))
|
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
-
+
|
NULL, &si, &pi))
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
}
objc_autoreleasePoolPop(pool);
_process = pi.hProcess;
_handle = pi.hProcess;
CloseHandle(pi.hThread);
CloseHandle(_readPipe[1]);
CloseHandle(_writePipe[0]);
} @catch (id e) {
[self release];
@throw e;
|
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
|
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
|
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
|
{
if (_readPipe[0] == NULL)
@throw [OFNotOpenException exceptionWithObject: self];
[self closeForWriting];
CloseHandle(_readPipe[0]);
if (_process != INVALID_HANDLE_VALUE) {
TerminateProcess(_process, 0);
CloseHandle(_process);
if (_handle != INVALID_HANDLE_VALUE) {
TerminateProcess(_handle, 0);
CloseHandle(_handle);
}
_process = INVALID_HANDLE_VALUE;
_handle = INVALID_HANDLE_VALUE;
_readPipe[0] = NULL;
[super close];
}
- (int)waitForTermination
{
if (_readPipe[0] == NULL)
@throw [OFNotOpenException exceptionWithObject: self];
if (_process != INVALID_HANDLE_VALUE) {
if (_handle != INVALID_HANDLE_VALUE) {
DWORD exitCode;
WaitForSingleObject(_process, INFINITE);
WaitForSingleObject(_handle, INFINITE);
if (GetExitCodeProcess(_process, &exitCode))
if (GetExitCodeProcess(_handle, &exitCode))
_status = exitCode;
else
_status = GetLastError();
CloseHandle(_process);
_process = INVALID_HANDLE_VALUE;
CloseHandle(_handle);
_handle = INVALID_HANDLE_VALUE;
}
return _status;
}
@end
|