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 (Errno2String[EBADE]) {
71  free((char*)Errno2String[EBADE]);
72  }
73 
74  Errno2String[EBADE] = "authentication failed - possible invalid exchange";
75 #endif
76 
77  // Supply generic message for missing ones
78  //
79  for (int i = 1; i < lastGood; i++)
80  {if (!Errno2String[i])
81  {snprintf(eBuff, sizeof(eBuff), "unknown error %d", ERRNOBASE + i);
82  Errno2String[i] = strdup(eBuff);
83  }
84  }
85 
86 // Return the highest valid one
87 //
88  Errno2String[0] = "no error";
89  return lastGood;
90 }
91 
92 int maxErrno = initErrTable();
93 }
94 
95 /******************************************************************************/
96 /* X r d S y s E 2 T */
97 /******************************************************************************/
98 
99 const char *XrdSysE2T(int errcode)
100 {
101  char eBuff[80];
102 
103 // Check if we can return this immediately
104 //
105  if (errcode == 0) return Errno2String[0];
106  if (errcode > ERRNOBASE && errcode <= ERRNOBASE + maxErrno)
107  return Errno2String[errcode - ERRNOBASE];
108 
109 // If this is a negative value, then return a generic message
110 //
111  if (errcode < 0) return "negative error";
112 
113 // Our errno registration wasn't sufficient, so check if it's already
114 // registered and if not, register it.
115 //
116  e2sMutex.Lock();
117  std::string &eTxt = e2sMap[errcode];
118  if (!eTxt.size())
119  {snprintf(eBuff, sizeof(eBuff), "unknown error %d", errcode);
120  eTxt = std::string(eBuff);
121  e2sMap[errcode] = eTxt;
122  }
123 
124 // Return the result
125 //
126  e2sMutex.UnLock();
127  return eTxt.c_str();
128 }
#define ERRNOBASE
Definition: XrdSysE2T.cc:40
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:99