// // 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]; [filteredArguments release]; 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