Read or write of errno
ID |
objectivec.maintainability.avoid_errno |
Severity |
info |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Error Handling |
Language |
Objective-C |
Description
Reports any read or write of the errno global in Objective-C code, both direct assignment and comparison or read.
Rationale
errno is ambient, process-wide mutable state that any library call along the way can overwrite, so a read of errno is only meaningful immediately after the one call whose failure it is documented to report, and only when nothing else runs in between. Threading it through application logic couples that logic to an implicit global instead of an explicit, testable status. Cocoa already offers an explicit alternative in NSError, so errno in an Objective-C code base is normally a leftover from wrapped C or POSIX calls.
The following code illustrates the pattern detected by this rule:
@implementation FileHelper
- (BOOL)readFileAtPath:(NSString *)path {
// FLAGGED: Read or write of errno
errno = 0;
FILE *fp = fopen([path UTF8String], "r");
// FLAGGED: Read or write of errno
if (fp == NULL && errno == EACCES) {
// FLAGGED: Read or write of errno
NSLog(@"open failed: %s", strerror(errno));
return NO;
}
fclose(fp);
return YES;
}
@end
Remediation
Propagate the failure through an NSError ** out-parameter or the method’s own return value instead of relying on errno. Where a wrapped POSIX call must inspect errno, confine the read to the statement immediately after that call and convert it into an NSError before it travels any further.