1 /*
2 *
3 * This file is part of MUMPS 5.1.2, released
4 * on Mon Oct 2 07:37:01 UTC 2017
5 *
6 *
7 * Copyright 1991-2017 CERFACS, CNRS, ENS Lyon, INP Toulouse, Inria,
8 * University of Bordeaux.
9 *
10 * This version of MUMPS is provided to you free of charge. It is
11 * released under the CeCILL-C license:
12 * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
13 *
14 */
15 #include "mumps_io_err.h"
16 #include "mumps_io_basic.h"
17 #include "mumps_c_types.h"
18 #if defined( MUMPS_WIN32 )
19 # include <string.h>
20 #endif
21 /* Exported global variables */
22 char* mumps_err;
23 MUMPS_INT* dim_mumps_err;
24 MUMPS_INT mumps_err_max_len;
25 MUMPS_INT err_flag;
26 #if ! ( defined(MUMPS_WIN32) || defined(WITHOUT_PTHREAD) )
27 pthread_mutex_t err_mutex;
28 #endif /* ! ( MUMPS_WIN32 || WITHOUT_PTHREAD ) */
29 /* Functions */
30 /* Keeps a C pointer to store error description string that will be
31 displayed by the Fortran layers.
32 * dim contains the size of the Fortran character array to store the
33 description.
34 */
35 void MUMPS_CALL
MUMPS_LOW_LEVEL_INIT_ERR_STR(MUMPS_INT * dim,char * err_str,mumps_ftnlen l1)36 MUMPS_LOW_LEVEL_INIT_ERR_STR(MUMPS_INT *dim, char* err_str, mumps_ftnlen l1){
37 mumps_err = err_str;
38 dim_mumps_err = (MUMPS_INT *) dim;
39 mumps_err_max_len = (MUMPS_INT) *dim;
40 err_flag = 0;
41 return;
42 }
43 #if ! defined(MUMPS_WIN32) && ! defined(WITHOUT_PTHREAD)
44 MUMPS_INLINE MUMPS_INT
mumps_io_protect_err()45 mumps_io_protect_err()
46 {
47 if(mumps_io_flag_async==IO_ASYNC_TH){
48 pthread_mutex_lock(&err_mutex);
49 }
50 return 0;
51 }
52 MUMPS_INLINE MUMPS_INT
mumps_io_unprotect_err()53 mumps_io_unprotect_err()
54 {
55 if(mumps_io_flag_async==IO_ASYNC_TH){
56 pthread_mutex_unlock(&err_mutex);
57 }
58 return 0;
59 }
60 MUMPS_INT
mumps_io_init_err_lock()61 mumps_io_init_err_lock()
62 {
63 pthread_mutex_init(&err_mutex,NULL);
64 return 0;
65 }
66 MUMPS_INT
mumps_io_destroy_err_lock()67 mumps_io_destroy_err_lock()
68 {
69 pthread_mutex_destroy(&err_mutex);
70 return 0;
71 }
72 MUMPS_INT
mumps_check_error_th()73 mumps_check_error_th()
74 {
75 /* If err_flag != 0, then error_str is set */
76 return err_flag;
77 }
78 #endif /* MUMPS_WIN32 && WITHOUT_PTHREAD */
79 MUMPS_INT
mumps_io_error(MUMPS_INT mumps_errno,const char * desc)80 mumps_io_error(MUMPS_INT mumps_errno, const char* desc)
81 {
82 MUMPS_INT len;
83 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
84 mumps_io_protect_err();
85 #endif
86 if(err_flag == 0){
87 strncpy(mumps_err, desc, mumps_err_max_len);
88 /* mumps_err is a FORTRAN string, we do not care about adding a final 0 */
89 len = (MUMPS_INT) strlen(desc);
90 *dim_mumps_err = (len <= mumps_err_max_len ) ? len : mumps_err_max_len;
91 err_flag = mumps_errno;
92 }
93 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
94 mumps_io_unprotect_err();
95 #endif
96 return mumps_errno;
97 }
98 MUMPS_INT
mumps_io_sys_error(MUMPS_INT mumps_errno,const char * desc)99 mumps_io_sys_error(MUMPS_INT mumps_errno, const char* desc)
100 {
101 MUMPS_INT len = 2; /* length of ": " */
102 const char* _desc;
103 char* _err;
104 #if defined( MUMPS_WIN32 )
105 MUMPS_INT _err_len;
106 #endif
107 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
108 mumps_io_protect_err();
109 #endif
110 if(err_flag==0){
111 if(desc == NULL) {
112 _desc = "";
113 } else {
114 len += (MUMPS_INT) strlen(desc);
115 _desc = desc;
116 }
117 #if ! defined( MUMPS_WIN32 )
118 _err = strerror(errno);
119 len += (MUMPS_INT) strlen(_err);
120 snprintf(mumps_err, mumps_err_max_len, "%s: %s", _desc, _err);
121 /* mumps_err is a FORTRAN string, we do not care about adding a final 0 */
122 #else
123 /* This a VERY UGLY workaround for snprintf: this function has been
124 * integrated quite lately into the ANSI stdio: some windows compilers are
125 * not up-to-date yet. */
126 if( len >= mumps_err_max_len - 1 ) { /* then do not print sys error msg at all */
127 len -= 2;
128 len = (len >= mumps_err_max_len ) ? mumps_err_max_len - 1 : len;
129 _err = strdup( _desc );
130 _err[len] = '\0';
131 sprintf(mumps_err, "%s", _err);
132 } else {
133 _err = strdup(strerror(errno));
134 _err_len = (MUMPS_INT) strlen(_err);
135 /* We will use sprintf, so make space for the final '\0' ! */
136 if((len + _err_len) >= mumps_err_max_len) {
137 /* truncate _err, not to overtake mumps_err_max_len at the end. */
138 _err[mumps_err_max_len - len - 1] = '\0';
139 len = mumps_err_max_len - 1;
140 } else {
141 len += _err_len;
142 }
143 sprintf(mumps_err, "%s: %s", _desc, _err);
144 }
145 free(_err);
146 #endif
147 *dim_mumps_err = (len <= mumps_err_max_len ) ? len : mumps_err_max_len;
148 err_flag = mumps_errno;
149 }
150 #if ! defined( MUMPS_WIN32 ) && ! defined( WITHOUT_PTHREAD )
151 mumps_io_unprotect_err();
152 #endif
153 return mumps_errno;
154 }
155