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