/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Los Alamos National Security, LLC. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "opal_config.h" #ifdef HAVE_STRING_H #include #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #include "opal/util/error.h" #include "opal/util/opal_sos.h" #include "opal/constants.h" #define MAX_CONVERTERS 5 #define MAX_CONVERTER_PROJECT_LEN 10 struct converter_info_t { int init; char project[MAX_CONVERTER_PROJECT_LEN]; int err_base; int err_max; opal_err2str_fn_t converter; }; typedef struct converter_info_t converter_info_t; /* all default to NULL */ converter_info_t converters[MAX_CONVERTERS]; static int opal_strerror_int(int errnum, const char **str) { int i, ret = OPAL_SUCCESS; *str = NULL; for (i = 0 ; i < MAX_CONVERTERS ; ++i) { if (0 != converters[i].init && errnum < converters[i].err_base && converters[i].err_max < errnum) { ret = converters[i].converter(errnum, str); break; } } return ret; } /* caller must free string */ static int opal_strerror_unknown(int errnum, char **str) { int i; *str = NULL; for (i = 0 ; i < MAX_CONVERTERS ; ++i) { if (0 != converters[i].init) { if (errnum < converters[i].err_base && errnum > converters[i].err_max) { asprintf(str, "Unknown error: %d (%s error %d)", errnum, converters[i].project, errnum - converters[i].err_base); return OPAL_SUCCESS; } } } asprintf(str, "Unknown error: %d", errnum); return OPAL_SUCCESS; } void opal_perror(int errnum, const char *msg) { int ret; const char* errmsg; ret = opal_strerror_int(errnum, &errmsg); if (NULL != msg && OPAL_SOS_GET_ERROR_CODE(errnum) != OPAL_ERR_IN_ERRNO) { fprintf(stderr, "%s: ", msg); } if (OPAL_SUCCESS != ret) { if (OPAL_SOS_GET_ERROR_CODE(errnum) == OPAL_ERR_IN_ERRNO) { perror(msg); } else { char *ue_msg; ret = opal_strerror_unknown(errnum, &ue_msg); fprintf(stderr, "%s\n", ue_msg); free(ue_msg); } } else { fprintf(stderr, "%s\n", errmsg); } fflush(stderr); } /* big enough to hold long version */ #define UNKNOWN_RETBUF_LEN 50 static char unknown_retbuf[UNKNOWN_RETBUF_LEN]; const char * opal_strerror(int errnum) { int ret; const char* errmsg; if (OPAL_SOS_GET_ERROR_CODE(errnum) == OPAL_ERR_IN_ERRNO) { return strerror(errno); } ret = opal_strerror_int(errnum, &errmsg); if (OPAL_SUCCESS != ret) { char *ue_msg; ret = opal_strerror_unknown(errnum, &ue_msg); snprintf(unknown_retbuf, UNKNOWN_RETBUF_LEN, "%s", ue_msg); free(ue_msg); errno = EINVAL; return (const char*) unknown_retbuf; } else { return errmsg; } } int opal_strerror_r(int errnum, char *strerrbuf, size_t buflen) { const char* errmsg; int ret, len; ret = opal_strerror_int(errnum, &errmsg); if (OPAL_SUCCESS != ret) { if (OPAL_SOS_GET_ERROR_CODE(errnum) == OPAL_ERR_IN_ERRNO) { char *tmp = strerror(errno); strncpy(strerrbuf, tmp, buflen); return OPAL_SUCCESS; } else { char *ue_msg; ret = opal_strerror_unknown(errnum, &ue_msg); len = snprintf(strerrbuf, buflen, "%s", ue_msg); free(ue_msg); if (len > (int) buflen) { errno = ERANGE; return OPAL_ERR_OUT_OF_RESOURCE; } else { errno = EINVAL; return OPAL_SUCCESS; } } } else { len = snprintf(strerrbuf, buflen, "%s", errmsg); if (len > (int) buflen) { errno = ERANGE; return OPAL_ERR_OUT_OF_RESOURCE; } else { return OPAL_SUCCESS; } } } int opal_error_register(const char *project, int err_base, int err_max, opal_err2str_fn_t converter) { int i; for (i = 0 ; i < MAX_CONVERTERS ; ++i) { if (0 == converters[i].init) { converters[i].init = 1; strncpy(converters[i].project, project, MAX_CONVERTER_PROJECT_LEN); converters[i].project[MAX_CONVERTER_PROJECT_LEN-1] = '\0'; converters[i].err_base = err_base; converters[i].err_max = err_max; converters[i].converter = converter; return OPAL_SUCCESS; } } return OPAL_ERR_OUT_OF_RESOURCE; }