@@ -104,10 +104,9 @@ @implementation SSYTasker
104
104
@synthesize error = m_error ;
105
105
@synthesize delegate = m_delegate ;
106
106
107
- - (void )processNote : (NSNotification *)note
108
- pipeName : (NSString *)pipeName
109
- intoData : (NSMutableData *)mutableData {
110
- NSFileHandle * fileHandle = (NSFileHandle *)[note object ] ;
107
+ - (void )eatFromFilehandle : (NSFileHandle *)fileHandle
108
+ pipeName : (NSString *)pipeName
109
+ intoData : (NSMutableData *)mutableData {
111
110
NSError * error = nil ;
112
111
NSData * data = [fileHandle availableDataError_p: &error] ;
113
112
if (error) {
@@ -132,28 +131,38 @@ - (void)processNote:(NSNotification*)note
132
131
}
133
132
}
134
133
135
- - (void )eatStdoutNote : ( NSNotification *) note {
134
+ - (void )eatStdoutFromFileHandle : ( NSFileHandle *) fileHandle {
136
135
NSMutableData * mutableData = [self stdoutData ] ;
137
136
if (!mutableData) {
138
137
mutableData = [[NSMutableData alloc ] init ] ;
139
138
[self setStdoutData: mutableData] ;
140
139
}
141
140
142
- [self processNote: note
143
- pipeName: @" stdout"
144
- intoData: mutableData];
141
+ [self eatFromFilehandle: fileHandle
142
+ pipeName: @" stdout"
143
+ intoData: mutableData] ;
145
144
}
146
145
147
- - (void )eatStderrNote : (NSNotification *)note {
146
+ - (void )eatStdoutNote : (NSNotification *)note {
147
+ NSFileHandle * fileHandle = [note object ] ;
148
+ [self eatStdoutFromFileHandle: fileHandle] ;
149
+ }
150
+
151
+ - (void )eatStderrFromFileHandle : (NSFileHandle *)fileHandle {
148
152
NSMutableData * mutableData = [self stderrData ] ;
149
153
if (!mutableData) {
150
154
mutableData = [[NSMutableData alloc ] init ] ;
151
155
[self setStderrData: mutableData] ;
152
156
}
153
157
154
- [self processNote: note
155
- pipeName: @" stderr"
156
- intoData: mutableData];
158
+ [self eatFromFilehandle: fileHandle
159
+ pipeName: @" stderr"
160
+ intoData: mutableData];
161
+ }
162
+
163
+ - (void )eatStderrNote : (NSNotification *)note {
164
+ NSFileHandle * fileHandle = [note object ] ;
165
+ [self eatStderrFromFileHandle: fileHandle];
157
166
}
158
167
159
168
- (void )taskTerminatedNote : (NSNotification *)note {
@@ -282,7 +291,7 @@ - (NSInteger)runCommand:(NSString*)launchPath
282
291
BOOL keepRunning = [runLoop runMode: NSDefaultRunLoopMode
283
292
beforeDate: [NSDate distantFuture ]] ;
284
293
if (!keepRunning) {
285
- [self setIsTaskDone: YES ] ;
294
+ [self setIsTaskDone: YES ] ;
286
295
}
287
296
// That's all. Actual work is done by notification handlers.
288
297
// Just run the loop again, to wait for next notification or done.
@@ -293,6 +302,15 @@ - (NSInteger)runCommand:(NSString*)launchPath
293
302
294
303
exitStatus = [task terminationStatus ] ;
295
304
305
+ // Added the following to fix bug, 20130712, which caused stderr or
306
+ // stdout to be not returned about 0.5% of the time. Apparently there
307
+ // is some kind of race condition wherein an NSTask can terminate
308
+ // before the final notification of available stdout or stderr has
309
+ // been processed, or something like that. Anyhow, it took me two days
310
+ // to figure this out. This fixed it…
311
+ [self eatStdoutFromFileHandle: fileStdout] ;
312
+ [self eatStderrFromFileHandle: fileStderr] ;
313
+
296
314
[[NSNotificationCenter defaultCenter ] removeObserver: self ] ;
297
315
}
298
316
0 commit comments