2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <utilities/SecCFError.h>
26 #include <utilities/SecCFRelease.h>
27 #include <utilities/debugging.h>
29 bool SecKernError(kern_return_t result
, CFErrorRef
*error
, CFStringRef format
, ...) {
30 if (!result
) return true;
33 CFIndex code
= result
;
34 CFErrorRef previousError
= *error
;
37 va_start(args
, format
);
38 SecCFCreateErrorWithFormatAndArguments(code
, kSecKernDomain
, previousError
, error
, NULL
, format
, args
);
44 bool SecCheckErrno(int result
, CFErrorRef
*error
, CFStringRef format
, ...) {
45 if (result
== 0) return true;
49 CFIndex code
= errnum
;
50 CFErrorRef previousError
= *error
;
53 va_start(args
, format
);
54 CFStringRef message
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, format
, args
);
56 SecCFCreateErrorWithFormat(code
, kSecErrnoDomain
, previousError
, error
, NULL
, CFSTR("%@: [%d] %s"), message
, errnum
, strerror(errnum
));
57 CFReleaseSafe(message
);
62 bool SecError(OSStatus status
, CFErrorRef
*error
, CFStringRef format
, ...) {
63 if (status
== 0) return true;
66 CFIndex code
= status
;
67 CFErrorRef previousError
= *error
;
70 va_start(args
, format
);
71 SecCFCreateErrorWithFormatAndArguments(code
, kSecErrorDomain
, previousError
, error
, NULL
, format
, args
);
77 bool SecCFCreateError(CFIndex errorCode
, CFStringRef domain
, CFStringRef descriptionString
,
78 CFErrorRef previousError
, CFErrorRef
*newError
)
80 #pragma clang diagnostic push
81 #pragma GCC diagnostic ignored "-Wformat-security"
82 return SecCFCreateErrorWithFormat(errorCode
, domain
, previousError
, newError
, NULL
, descriptionString
);
83 #pragma clang diagnostic pop
86 bool SecCFCreateErrorWithFormat(CFIndex errorCode
, CFStringRef domain
, CFErrorRef previousError
, CFErrorRef
*newError
,
87 CFDictionaryRef formatoptions
, CFStringRef format
, ...)
90 va_start(args
, format
);
92 bool result
= SecCFCreateErrorWithFormatAndArguments(errorCode
, domain
, previousError
, newError
, formatoptions
, format
, args
);
99 bool SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode
, CFStringRef domain
,
100 CFErrorRef previousError
, CFErrorRef
*newError
,
101 CFDictionaryRef formatoptions
, CFStringRef format
, va_list args
)
103 if (newError
&& !(*newError
)) {
104 CFStringRef formattedString
= CFStringCreateWithFormatAndArguments(NULL
, formatoptions
, format
, args
);
106 const void* keys
[2] = { kCFErrorDescriptionKey
, kCFErrorUnderlyingErrorKey
};
107 const void* values
[2] = { formattedString
, previousError
};
108 const CFIndex numEntriesToUse
= (previousError
!= NULL
) ? 2 : 1;
110 *newError
= CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault
, domain
, errorCode
,
111 keys
, values
, numEntriesToUse
);
113 CFReleaseNull(formattedString
);
115 secnotice("error", "encapsulated %@ with new error: %@", previousError
, *newError
);
117 if (previousError
&& newError
&& (previousError
!= *newError
)) {
118 secnotice("error", "dropping %@", previousError
);
119 CFRelease(previousError
);