error.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 299 行
C
299 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifdef DEBUGstatic const char CVS_ID[] = "@(#) $RCSfile: error.c,v $ $Revision: 1.2 $ $Date: 2000/05/17 20:19:23 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG *//* * error.c * * This file contains the code implementing the per-thread error * stacks upon which most NSS routines report their errors. */#ifndef BASE_H#include "base.h"#endif /* BASE_H *//* * The stack itself has a header, and a sequence of integers. * The header records the amount of space (as measured in stack * slots) already allocated for the stack, and the count of the * number of records currently being used. */struct stack_header_str { PRUint16 space; PRUint16 count;};struct error_stack_str { struct stack_header_str header; PRInt32 stack[1];};typedef struct error_stack_str error_stack;/* * error_stack_index * * Thread-private data must be indexed. This is that index. * See PR_NewThreadPrivateIndex for more information. */static PRUintn error_stack_index;/* * call_once * * The thread-private index must be obtained (once!) at runtime. * This block is used for that one-time call. */static PRCallOnceType error_call_once;/* * error_once_function * * This is the once-called callback. */static PRStatuserror_once_function( void){ return nss_NewThreadPrivateIndex(&error_stack_index); /* return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free); */}/* * error_get_my_stack * * This routine returns the calling thread's error stack, creating * it if necessary. It may return NULL upon error, which implicitly * means that it ran out of memory. */static error_stack *error_get_my_stack( void){ PRStatus st; error_stack *rv; PRUintn new_size; PRUint32 new_bytes; error_stack *new_stack; if( 0 == error_stack_index ) { st = PR_CallOnce(&error_call_once, error_once_function); if( PR_SUCCESS != st ) { return (error_stack *)NULL; } } rv = (error_stack *)nss_GetThreadPrivate(error_stack_index); if( (error_stack *)NULL == rv ) { /* Doesn't exist; create one */ new_size = 16; } else { if( rv->header.count == rv->header.space ) { /* Too small, expand it */ new_size = rv->header.space + 16; } else { /* Okay, return it */ return rv; } } new_bytes = (new_size * sizeof(PRInt32)) + sizeof(struct stack_header_str); /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */ if( (error_stack *)NULL == rv ) { new_stack = PR_Calloc(1, new_bytes); } else { new_stack = PR_Realloc(rv, new_bytes); } if( (error_stack *)NULL != new_stack ) { new_stack->header.space = new_size; } /* Set the value, whether or not the allocation worked */ nss_SetThreadPrivate(error_stack_index, new_stack); return new_stack;}/* * The error stack * * The public methods relating to the error stack are: * * NSS_GetError * NSS_GetErrorStack * * The nonpublic methods relating to the error stack are: * * nss_SetError * nss_ClearErrorStack * *//* * NSS_GetError * * This routine returns the highest-level (most general) error set * by the most recent NSS library routine called by the same thread * calling this routine. * * This routine cannot fail. However, it may return zero, which * indicates that the previous NSS library call did not set an error. * * Return value: * 0 if no error has been set * A nonzero error number */NSS_IMPLEMENT PRInt32NSS_GetError( void){ error_stack *es = error_get_my_stack(); if( (error_stack *)NULL == es ) { return NSS_ERROR_NO_MEMORY; /* Good guess! */ } if( 0 == es->header.count ) { return 0; } return es->stack[ es->header.count-1 ];}/* * NSS_GetErrorStack * * This routine returns a pointer to an array of integers, containing * the entire sequence or "stack" of errors set by the most recent NSS * library routine called by the same thread calling this routine. * NOTE: the caller DOES NOT OWN the memory pointed to by the return * value. The pointer will remain valid until the calling thread * calls another NSS routine. The lowest-level (most specific) error * is first in the array, and the highest-level is last. The array is * zero-terminated. This routine may return NULL upon error; this * indicates a low-memory situation. * * Return value: * NULL upon error, which is an implied NSS_ERROR_NO_MEMORY * A NON-caller-owned pointer to an array of integers */NSS_IMPLEMENT PRInt32 *NSS_GetErrorStack( void){ error_stack *es = error_get_my_stack(); if( (error_stack *)NULL == es ) { return (PRInt32 *)NULL; } /* Make sure it's terminated */ es->stack[ es->header.count ] = 0; return es->stack;}/* * nss_SetError * * This routine places a new error code on the top of the calling * thread's error stack. Calling this routine wiht an error code * of zero will clear the error stack. */NSS_IMPLEMENT voidnss_SetError( PRUint32 error){ error_stack *es; if( 0 == error ) { nss_ClearErrorStack(); return; } es = error_get_my_stack(); if( (error_stack *)NULL == es ) { /* Oh, well. */ return; } es->stack[ es->header.count ] = error; es->header.count++; return;}/* * nss_ClearErrorStack * * This routine clears the calling thread's error stack. */NSS_IMPLEMENT voidnss_ClearErrorStack( void){ error_stack *es = error_get_my_stack(); if( (error_stack *)NULL == es ) { /* Oh, well. */ return; } es->header.count = 0; es->stack[0] = 0; return;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?