5 // Created by Mitch Adler on 7/18/12.
6 // Copyright (c) 2012 Apple Inc. All rights reserved.
9 #include <Security/SecBase.h>
10 #include <utilities/SecCFError.h>
11 #include <utilities/SecCFRelease.h>
12 #include <utilities/debugging.h>
14 bool SecKernError(kern_return_t result
, CFErrorRef
*error
, CFStringRef format
, ...) {
15 if (!result
) return true;
18 CFIndex code
= result
;
19 CFErrorRef previousError
= *error
;
22 va_start(args
, format
);
23 SecCFCreateErrorWithFormatAndArguments(code
, kSecKernDomain
, previousError
, error
, NULL
, format
, args
);
29 bool SecCheckErrno(int result
, CFErrorRef
*error
, CFStringRef format
, ...) {
30 if (result
== 0) return true;
34 CFIndex code
= errnum
;
35 CFErrorRef previousError
= *error
;
38 va_start(args
, format
);
39 CFStringRef message
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, format
, args
);
41 SecCFCreateErrorWithFormat(code
, kSecErrnoDomain
, previousError
, error
, NULL
, CFSTR("%@: [%d] %s"), message
, errnum
, strerror(errnum
));
42 CFReleaseSafe(message
);
47 bool SecError(OSStatus status
, CFErrorRef
*error
, CFStringRef format
, ...) {
48 if (status
== errSecSuccess
) return true;
51 CFIndex code
= status
;
52 CFErrorRef previousError
= *error
;
55 va_start(args
, format
);
56 SecCFCreateErrorWithFormatAndArguments(code
, kSecErrorDomain
, previousError
, error
, NULL
, format
, args
);
63 void SecCFCreateError(CFIndex errorCode
, CFStringRef domain
, CFStringRef descriptionString
,
64 CFErrorRef previousError
, CFErrorRef
*newError
)
66 #pragma clang diagnostic push
67 #pragma GCC diagnostic ignored "-Wformat-security"
68 SecCFCreateErrorWithFormat(errorCode
, domain
, previousError
, newError
, NULL
, descriptionString
);
69 #pragma clang diagnostic pop
72 void SecCFCreateErrorWithFormat(CFIndex errorCode
, CFStringRef domain
, CFErrorRef previousError
, CFErrorRef
*newError
,
73 CFDictionaryRef formatoptions
, CFStringRef format
, ...)
76 va_start(args
, format
);
78 SecCFCreateErrorWithFormatAndArguments(errorCode
, domain
, previousError
, newError
, formatoptions
, format
, args
);
83 void SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode
, CFStringRef domain
,
84 CFErrorRef previousError
, CFErrorRef
*newError
,
85 CFDictionaryRef formatoptions
, CFStringRef format
, va_list args
)
87 if (newError
&& !(*newError
)) {
88 CFStringRef formattedString
= CFStringCreateWithFormatAndArguments(NULL
, formatoptions
, format
, args
);
90 const void* keys
[2] = { kCFErrorDescriptionKey
, kCFErrorUnderlyingErrorKey
};
91 const void* values
[2] = { formattedString
, previousError
};
92 const CFIndex numEntriesToUse
= (previousError
!= NULL
) ? 2 : 1;
94 *newError
= CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault
, domain
, errorCode
,
95 keys
, values
, numEntriesToUse
);
97 CFReleaseNull(formattedString
);
99 secnotice("error", "encapsulated %@ with new error: %@", previousError
, *newError
);
101 if (previousError
&& newError
&& (previousError
!= *newError
)) {
102 secnotice("error", "dropping %@", previousError
);
103 CFRelease(previousError
);