forked from dgrijalva/gitx
-
Notifications
You must be signed in to change notification settings - Fork 76
/
PBEasyPipe.m
155 lines (124 loc) · 4.39 KB
/
PBEasyPipe.m
1
2
3
4
5
6
7
8
9
10
11
12
13
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//
// PBEasyPipe.m
// GitX
//
// Created by Pieter de Bie on 16-06-08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "PBEasyPipe.h"
@implementation PBEasyPipe
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args
{
return [self handleForCommand:cmd withArgs:args inDir:nil];
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir
{
NSMutableArray *filteredArguments = [[NSMutableArray alloc] init];
for (NSString *param in args) {
if ([param length] > 0) {
[filteredArguments addObject:param];
}
}
NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:cmd];
[task setArguments:filteredArguments];
if (dir)
[task setCurrentDirectoryPath:dir];
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Show Debug Messages"])
DLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#ifdef CLI
DLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#endif
NSPipe* pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:pipe];
return task;
}
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
[task launch];
return handle;
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
retValue:(int *) ret
{
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:nil retValue:ret];
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
inputString:(NSString *) input
retValue:(int *) ret
{
return [self outputForCommand:cmd withArgs:args inDir:dir byExtendingEnvironment:nil inputString:input retValue:ret];
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
byExtendingEnvironment:(NSDictionary *)dict
inputString:(NSString *) input
retValue:(int *) ret
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
if (dict) {
NSMutableDictionary *env = [[[NSProcessInfo processInfo] environment] mutableCopy];
[env addEntriesFromDictionary:dict];
[task setEnvironment:env];
}
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
if (input) {
[task setStandardInput:[NSPipe pipe]];
NSFileHandle *inHandle = [[task standardInput] fileHandleForWriting];
[inHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[inHandle closeFile];
}
[task launch];
NSData* data = [handle readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!string)
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
// Strip trailing newline
if ([string hasSuffix:@"\n"])
string = [string substringToIndex:[string length]-1];
[task waitUntilExit];
if (ret)
*ret = [task terminationStatus];
return string;
}
// We don't use the above function because then we'd have to wait until the program was finished
// with running
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
[task launch];
// This can cause a "Bad file descriptor"... when?
NSData *data;
@try {
data = [handle readDataToEndOfFile];
}
@catch (NSException * e) {
DLog(@"Got a bad file descriptor in %@!", NSStringFromSelector(_cmd));
if ([NSThread currentThread] != [NSThread mainThread])
[task waitUntilExit];
return nil;
}
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!string)
string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
// Strip trailing newline
if ([string hasSuffix:@"\n"])
string = [string substringToIndex:[string length]-1];
if ([NSThread currentThread] != [NSThread mainThread])
[task waitUntilExit];
return string;
}
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args
{
return [self outputForCommand:cmd withArgs:args inDir:nil];
}
@end