XRootD
XrdSysE2T.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S y s E 2 T . c c */
4 /* */
5 /*(c) 2019 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /*Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Deprtment of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include <cstdio>
31 #include <cstring>
32 #include <map>
33 #include <string>
34 
35 #include "XrdSys/XrdSysPthread.hh"
36 
37 #ifdef __GNU__
38 #define ERRNOBASE 0x40000000
39 #else
40 #define ERRNOBASE 0
41 #endif
42 
43 namespace
44 {
45 static const int errSlots = 144;
46 XrdSysMutex e2sMutex;
47 std::map<int, std::string> e2sMap;
48  const char* Errno2String[errSlots] = {0};
49 
50 int initErrTable()
51 {
52  char *eTxt, eBuff[80];
53  int lastGood = 0;
54 
55 // Premap all known error codes.
56 //
57  for(int i = 1; i < errSlots; i++)
58  {eTxt = strerror(ERRNOBASE + i);
59  if (eTxt)
60  { eTxt = strdup(eTxt);
61  *eTxt = tolower(*eTxt);
62  Errno2String[i] = eTxt;
63  lastGood = i;
64  }
65  }
66  // NOTE: On systems without EAUTH (authentication error; currently all Glibc systems but GNU Hurd),
67  // EAUTH is remapped to EBADE ('invalid exchange'). Given there's no current XRootD use of a
68  // syscall that can return EBADE, we assume EBADE really means authentication denied.
69 #if defined(EBADE)
70  if (EBADE - ERRNOBASE > 0 && EBADE - ERRNOBASE < errSlots) {
71  if (Errno2String[EBADE - ERRNOBASE])
72  free((char*)Errno2String[EBADE - ERRNOBASE]);
73  Errno2String[EBADE - ERRNOBASE] = "authentication failed - possible invalid exchange";
74  if (EBADE - ERRNOBASE > lastGood)
75  lastGood = EBADE - ERRNOBASE;
76  }
77  else {
78  e2sMap[EBADE] = "authentication failed - possible invalid exchange";
79  }
80 #endif
81 
82  // Supply generic message for missing ones
83  //
84  for (int i = 1; i < lastGood; i++)
85  {if (!Errno2String[i])
86  {snprintf(eBuff, sizeof(eBuff), "unknown error %d", ERRNOBASE + i);
87  Errno2String[i] = strdup(eBuff);
88  }
89  }
90 
91 // Return the highest valid one
92 //
93  Errno2String[0] = "no error";
94  return lastGood;
95 }
96 
97 int maxErrno = initErrTable();
98 }
99 
100 /******************************************************************************/
101 /* X r d S y s E 2 T */
102 /******************************************************************************/
103 
104 const char *XrdSysE2T(int errcode)
105 {
106  char eBuff[80];
107 
108 // Check if we can return this immediately
109 //
110  if (errcode == 0) return Errno2String[0];
111  if (errcode > ERRNOBASE && errcode <= ERRNOBASE + maxErrno)
112  return Errno2String[errcode - ERRNOBASE];
113 
114 // If this is a negative value, then return a generic message
115 //
116  if (errcode < 0) return "negative error";
117 
118 // Our errno registration wasn't sufficient, so check if it's already
119 // registered and if not, register it.
120 //
121  e2sMutex.Lock();
122  std::string &eTxt = e2sMap[errcode];
123  if (!eTxt.size())
124  {snprintf(eBuff, sizeof(eBuff), "unknown error %d", errcode);
125  eTxt = std::string(eBuff);
126  e2sMap[errcode] = eTxt;
127  }
128 
129 // Return the result
130 //
131  e2sMutex.UnLock();
132  return eTxt.c_str();
133 }
#define ERRNOBASE
Definition: XrdSysE2T.cc:40
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104