Bug fix: Change improper usage of dot notation.

Calling methods which are not properties through use of dot notation is a
no-no in Apple's Objective-C 2.0 documentation. According to Apple it might
work but the compiler will not warn about any dangerous use cases.

The prominent example from the docs of how not to do it is "someObject.retain".

Here retain is a method and not a property so proper use is "[someObject retain]".
Unfortunately, often it is not clear if something in the API is merely an accessor
or a method which acts like an accessor but does more than the name might imply.

In this case, we can see this in PBEasyPipe where we have method calls like
"NSTask.standardOutput = ...". Even though they may look correct this can be
dangerous for obvious reasons. I assume hat this could also play a role in the appearance
of the "bad file descriptor" messages.
This commit is contained in:
André Berg
2009-10-20 03:40:34 +02:00
parent a7ce2abb06
commit 6c04aea44b
3 changed files with 68 additions and 92 deletions
+5
View File
@@ -13,9 +13,12 @@
#define CONN_TIMEOUT 5
#define BUFFER_SIZE 256
#import <objc/objc-auto.h> /* for objc_collect */
@implementation NSFileHandle(NSFileHandleExt)
-(NSString*)readLine {
// If the socket is closed, return an empty string
if ([self fileDescriptor] <= 0)
return @"";
@@ -62,6 +65,8 @@
retVal = [NSString stringWithCString: buffer encoding: NSISOLatin1StringEncoding];
free(buffer);
[[NSGarbageCollector defaultCollector] collectExhaustively];
return retVal;
}
+7 -19
View File
@@ -14,26 +14,14 @@
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args;
+ (NSFileHandle*) handleForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir;
+ (NSFileHandle *) handleForCommand:(NSString *)cmd withArgs:(NSArray *)args;
+ (NSFileHandle *) handleForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args;
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
retValue:(int *) ret;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
inputString:(NSString *)input
retValue:(int *) ret;
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
byExtendingEnvironment:(NSDictionary *)dict
inputString:(NSString *)input
retValue:(int *) ret;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir retValue:(int *)ret;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir inputString:(NSString *)input retValue:(int *)ret;
+ (NSString *) outputForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir byExtendingEnvironment:(NSDictionary *)dict inputString:(NSString *)input retValue:(int *)ret;
@end
+56 -73
View File
@@ -16,92 +16,75 @@
return [self handleForCommand:cmd withArgs:args inDir:nil];
}
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir
{
NSTask* task = [[NSTask alloc] init];
task.launchPath = cmd;
task.arguments = args;
if (dir)
task.currentDirectoryPath = dir;
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Show Debug Messages"])
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#ifdef CLI
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#endif
NSPipe* pipe = [NSPipe pipe];
task.standardOutput = 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];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
[task launch];
return handle;
}
+ (NSString*) outputForCommand:(NSString *) cmd
withArgs:(NSArray *) args
inDir:(NSString *) dir
retValue:(int *) ret
+ (NSTask *) taskForCommand:(NSString *)cmd withArgs:(NSArray *)args inDir:(NSString *)dir
{
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];
NSTask* task = [[NSTask alloc] init];
[task setLaunchPath:cmd];
[task setArguments:args];
if (dir)
[task setCurrentDirectoryPath:dir];
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"Show Debug Messages"])
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#ifdef CLI
NSLog(@"Starting command `%@ %@` in dir %@", cmd, [args componentsJoinedByString:@" "], dir);
#endif
NSPipe* pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
return task;
}
+ (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];
+ (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];
}
if (dict) {
NSMutableDictionary *env = [[[NSProcessInfo processInfo] environment] mutableCopy];
[env addEntriesFromDictionary:dict];
task.environment = env;
}
+ (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];
}
NSFileHandle* handle = [task.standardOutput fileHandleForReading];
+ (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 (input) {
task.standardInput = [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;
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
@@ -110,7 +93,7 @@
+ (NSString*) outputForCommand: (NSString*) cmd withArgs: (NSArray*) args inDir: (NSString*) dir
{
NSTask *task = [self taskForCommand:cmd withArgs:args inDir:dir];
NSFileHandle* handle = [task.standardOutput fileHandleForReading];
NSFileHandle* handle = [[task standardOutput] fileHandleForReading];
[task launch];
#warning This can cause a "Bad file descriptor"... when?