X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/c38e3ce98599a410a47dc10253faa4d5830f13b2..427c49bcad63d042b29ada2ac27e3dfc4845c779:/utilities/src/SecCFError.c diff --git a/utilities/src/SecCFError.c b/utilities/src/SecCFError.c new file mode 100644 index 00000000..cd259433 --- /dev/null +++ b/utilities/src/SecCFError.c @@ -0,0 +1,106 @@ +// +// SecCFError.c +// utilities +// +// Created by Mitch Adler on 7/18/12. +// Copyright (c) 2012 Apple Inc. All rights reserved. +// + +#include +#include +#include +#include + +bool SecKernError(kern_return_t result, CFErrorRef *error, CFStringRef format, ...) { + if (!result) return true; + if (error) { + va_list args; + CFIndex code = result; + CFErrorRef previousError = *error; + + *error = NULL; + va_start(args, format); + SecCFCreateErrorWithFormatAndArguments(code, kSecKernDomain, previousError, error, NULL, format, args); + va_end(args); + } + return false; +} + +bool SecCheckErrno(int result, CFErrorRef *error, CFStringRef format, ...) { + if (result == 0) return true; + if (error) { + va_list args; + int errnum = errno; + CFIndex code = errnum; + CFErrorRef previousError = *error; + + *error = NULL; + va_start(args, format); + CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args); + va_end(args); + SecCFCreateErrorWithFormat(code, kSecErrnoDomain, previousError, error, NULL, CFSTR("%@: [%d] %s"), message, errnum, strerror(errnum)); + CFReleaseSafe(message); + } + return false; +} + +bool SecError(OSStatus status, CFErrorRef *error, CFStringRef format, ...) { + if (status == errSecSuccess) return true; + if (error) { + va_list args; + CFIndex code = status; + CFErrorRef previousError = *error; + + *error = NULL; + va_start(args, format); + SecCFCreateErrorWithFormatAndArguments(code, kSecErrorDomain, previousError, error, NULL, format, args); + va_end(args); + } + return false; +} + + +void SecCFCreateError(CFIndex errorCode, CFStringRef domain, CFStringRef descriptionString, + CFErrorRef previousError, CFErrorRef *newError) +{ +#pragma clang diagnostic push +#pragma GCC diagnostic ignored "-Wformat-security" + SecCFCreateErrorWithFormat(errorCode, domain, previousError, newError, NULL, descriptionString); +#pragma clang diagnostic pop +} + +void SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRef previousError, CFErrorRef *newError, + CFDictionaryRef formatoptions, CFStringRef format, ...) +{ + va_list args; + va_start(args, format); + + SecCFCreateErrorWithFormatAndArguments(errorCode, domain, previousError, newError, formatoptions, format, args); + + va_end(args); +} + +void SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain, + CFErrorRef previousError, CFErrorRef *newError, + CFDictionaryRef formatoptions, CFStringRef format, va_list args) +{ + if (newError && !(*newError)) { + CFStringRef formattedString = CFStringCreateWithFormatAndArguments(NULL, formatoptions, format, args); + + const void* keys[2] = { kCFErrorDescriptionKey, kCFErrorUnderlyingErrorKey}; + const void* values[2] = { formattedString, previousError }; + const CFIndex numEntriesToUse = (previousError != NULL) ? 2 : 1; + + *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, domain, errorCode, + keys, values, numEntriesToUse); + + CFReleaseNull(formattedString); + if (previousError) + secnotice("error", "encapsulated %@ with new error: %@", previousError, *newError); + } else { + if (previousError && newError && (previousError != *newError)) { + secnotice("error", "dropping %@", previousError); + CFRelease(previousError); + } + } +}