diff --git a/src/clib/pio.h b/src/clib/pio.h index 2dd570831c5a..07f4b8b20c55 100644 --- a/src/clib/pio.h +++ b/src/clib/pio.h @@ -440,7 +440,7 @@ enum PIO_ERROR_HANDLERS #if defined(__cplusplus) extern "C" { #endif - const char *PIOc_strerror(int pioerr); + int PIOc_strerror(int pioerr, char *errstr); int PIOc_freedecomp(int iosysid, int ioid); int PIOc_inq_att (int ncid, int varid, const char *name, nc_type *xtypep, PIO_Offset *lenp); int PIOc_inq_format (int ncid, int *formatp); diff --git a/src/clib/pioc_support.c b/src/clib/pioc_support.c index 5c842d93984a..c60f4047a49d 100644 --- a/src/clib/pioc_support.c +++ b/src/clib/pioc_support.c @@ -21,43 +21,49 @@ int my_rank; * null is returned. * * @param pioerr the error code returned by a PIO function call. + * @param errmsg Pointer that will get the error message. It will be + * PIO_MAX_NAME chars or less. * - * @return Pointer to a constant string with the error message. + * @return 0 on success */ -const char *PIOc_strerror(int pioerr) +int +PIOc_strerror(int pioerr, char *errmsg) { /* System error? */ if(pioerr > 0) { const char *cp = (const char *)strerror(pioerr); - if(!cp) - return "Unknown Error"; - return cp; + if (cp) + strncpy(errmsg, cp, PIO_MAX_NAME); + else + strcpy(errmsg, "Unknown Error"); } - - /* Not an error? */ - if (pioerr == PIO_NOERR) - return "No error"; - - /* NetCDF error? */ + else if (pioerr == PIO_NOERR) + { + strcpy(errmsg, "No error"); + } + else if (pioerr <= NC2_ERR && pioerr >= NC4_LAST_ERROR) /* NetCDF error? */ + { #if defined( _PNETCDF) || defined(_NETCDF) - /* The if condition is somewhat confusing becuase netCDF uses - * negative error codes.*/ - if (pioerr <= NC2_ERR && pioerr >= NC4_LAST_ERROR) - return nc_strerror(pioerr); + strncpy(errmsg, nc_strerror(pioerr), NC_MAX_NAME); #else /* defined( _PNETCDF) || defined(_NETCDF) */ - if (pioerr <= NC2_ERR && pioerr >= NC4_LAST_ERROR) - return "NetCDF error code, PIO not built with netCDF."; + strcpy(errmsg, "NetCDF error code, PIO not built with netCDF."); #endif /* defined( _PNETCDF) || defined(_NETCDF) */ - - /* Handle PIO errors. */ - switch(pioerr) { - case PIO_EBADIOTYPE: - return "Bad IO type"; - default: - return "unknown PIO error"; } + else + { + /* Handle PIO errors. */ + switch(pioerr) { + case PIO_EBADIOTYPE: + strcpy(errmsg, "Bad IO type"); + break; + default: + strcpy(errmsg, "unknown PIO error"); + } + } + + return PIO_NOERR; } /** Set the logging level. Set to -1 for nothing, 0 for errors only, 1 diff --git a/src/flib/pio.F90 b/src/flib/pio.F90 index c415f7a6fb30..f5115cc57223 100644 --- a/src/flib/pio.F90 +++ b/src/flib/pio.F90 @@ -60,6 +60,7 @@ module pio PIO_get_chunk_cache, & PIO_set_var_chunk_cache, & PIO_get_var_chunk_cache +! PIO_strerror, & use pionfatt_mod, only : PIO_put_att => put_att, & PIO_get_att => get_att diff --git a/src/flib/pio_nf.F90 b/src/flib/pio_nf.F90 index 8aa74d06f9f1..a3cd06d92b9d 100644 --- a/src/flib/pio_nf.F90 +++ b/src/flib/pio_nf.F90 @@ -37,7 +37,8 @@ module pio_nf pio_set_var_chunk_cache , & pio_get_var_chunk_cache , & pio_redef , & - pio_set_log_level + pio_set_log_level +! pio_strerror ! pio_copy_att to be done interface pio_def_var @@ -194,6 +195,11 @@ module pio_nf set_log_level end interface pio_set_log_level + ! interface pio_strerror + ! module procedure & + ! strerror + ! end interface pio_strerror + interface pio_inquire module procedure & inquire_desc , & @@ -678,6 +684,28 @@ end function PIOc_set_log_level end interface ierr = PIOc_set_log_level(log_level) end function set_log_level +!> +!! @defgroup PIO_strerror +!< +!> +!! @ingroup PIO_strerror +!! Returns a descriptive string for an error code. +!! +!! @param errcode the error code +!! @retval a description of the error + !< + ! function strerror(errcode) result(errmsg) + ! integer, intent(in) :: errcode + ! Character(LEN=80) :: errmsg + ! interface + ! Function PIOc_strerror(errcode) BIND(C) + ! USE ISO_C_BINDING, ONLY: C_INT, C_PTR + ! Integer(C_INT), VALUE :: errcode + ! Type(C_PTR) :: PIOc_strerror + ! End Function PIOc_strerror + ! end interface + ! strerror = PIOc_strerror(errcode) + ! end function strerror !> !! @public !! @ingroup PIO_redef diff --git a/tests/unit/driver.F90 b/tests/unit/driver.F90 index d12d1d29cc2c..ced2c77af596 100644 --- a/tests/unit/driver.F90 +++ b/tests/unit/driver.F90 @@ -55,6 +55,8 @@ Program pio_unit_test_driver write(*,"(A,1x,I0,1x,A,1x,I0)") "Running unit tests with", ntasks, & "MPI tasks and stride of", stride +! print *, 'errcode =', -33, ' strerror = ', PIO_strerror(-33) + if (stride.gt.ntasks) then stride = ntasks write(*,"(A,1x,A,I0)") "WARNING: stride value in namelist is larger than", & diff --git a/tests/unit/test_names.c b/tests/unit/test_names.c index 5a191dcc06df..48884eedd827 100644 --- a/tests/unit/test_names.c +++ b/tests/unit/test_names.c @@ -171,8 +171,10 @@ check_strerror(int my_rank, int verbose) { for (int try = 0; try < NUM_TRIES; try++) { + char result[PIO_MAX_NAME]; + /* Get the error string for this errcode. */ - strcpy(errstr, PIOc_strerror(errcode[try])); + PIOc_strerror(errcode[try], errstr); /* Check that it was as expected. */ if (strcmp(errstr, expected[try]))