~ubuntu-branches/ubuntu/wily/libgpg-error/wily

« back to all changes in this revision

Viewing changes to src/strerror.c

  • Committer: Bazaar Package Importer
  • Author(s): Jose Carlos Garcia Sogo
  • Date: 2004-03-16 23:25:13 UTC
  • Revision ID: james.westby@ubuntu.com-20040316232513-u9dnue5r0i3egfkq
Tags: upstream-0.7
ImportĀ upstreamĀ versionĀ 0.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* strerror.c - Describing an error code.
 
2
   Copyright (C) 2003 g10 Code GmbH
 
3
 
 
4
   This file is part of libgpg-error.
 
5
 
 
6
   libgpg-error is free software; you can redistribute it and/or
 
7
   modify it under the terms of the GNU Lesser General Public License
 
8
   as published by the Free Software Foundation; either version 2.1 of
 
9
   the License, or (at your option) any later version.
 
10
 
 
11
   libgpg-error is distributed in the hope that it will be useful, but
 
12
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Lesser General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Lesser General Public
 
17
   License along with libgpg-error; if not, write to the Free
 
18
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
   02111-1307, USA.  */
 
20
 
 
21
#if HAVE_CONFIG_H
 
22
#include <config.h>
 
23
#endif
 
24
 
 
25
#include <stdlib.h>
 
26
#include <stdio.h>
 
27
#include <string.h>
 
28
#include <errno.h>
 
29
 
 
30
#include <gpg-error.h>
 
31
 
 
32
#include "gettext.h"
 
33
#include "err-codes.h"
 
34
 
 
35
/* Return a pointer to a string containing a description of the error
 
36
   code in the error value ERR.  This function is not thread-safe.  */
 
37
const char *
 
38
gpg_strerror (gpg_error_t err)
 
39
{
 
40
  gpg_err_code_t code = gpg_err_code (err);
 
41
 
 
42
  if (code & GPG_ERR_SYSTEM_ERROR)
 
43
    {
 
44
      int no = gpg_err_code_to_errno (code);
 
45
      if (no)
 
46
        return strerror (no);
 
47
      else
 
48
        code = GPG_ERR_UNKNOWN_ERRNO;
 
49
    }
 
50
  return dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]);
 
51
}
 
52
 
 
53
 
 
54
#ifdef HAVE_STRERROR_R
 
55
#ifdef STRERROR_R_CHAR_P
 
56
/* The GNU C library and probably some other systems have this weird
 
57
   variant of strerror_r.  */
 
58
 
 
59
/* Return a dynamically allocated string in *STR describing the system
 
60
   error NO.  If this call succeeds, return 1.  If this call fails due
 
61
   to a resource shortage, set *STR to NULL and return 1.  If this
 
62
   call fails because the error number is not valid, don't set *STR
 
63
   and return 0.  */
 
64
int
 
65
system_strerror_r (int no, char *buf, size_t buflen)
 
66
{
 
67
  char *errstr;
 
68
 
 
69
  errstr = strerror_r (no, buf, buflen);
 
70
  if (errstr != buf)
 
71
    {
 
72
      size_t errstr_len = strlen (errstr) + 1;
 
73
      size_t cpy_len = errstr_len < buflen ? errstr_len : buflen;
 
74
      memcpy (buf, errstr, cpy_len);
 
75
 
 
76
      return cpy_len == errstr_len ? 0 : ERANGE;
 
77
    }
 
78
  else
 
79
    {
 
80
      /* We can not tell if the buffer was large enough, but we can
 
81
         try to make a guess.  */
 
82
      if (strlen (buf) + 1 >= buflen)
 
83
        return ERANGE;
 
84
 
 
85
      return 0;
 
86
    }
 
87
}
 
88
 
 
89
#else   /* STRERROR_R_CHAR_P */
 
90
/* Now the POSIX version.  */
 
91
 
 
92
int
 
93
system_strerror_r (int no, char *buf, size_t buflen)
 
94
{
 
95
  return strerror_r (no, buf, buflen);
 
96
}
 
97
 
 
98
#endif  /* STRERROR_R_CHAR_P */
 
99
 
 
100
#else   /* HAVE_STRERROR_H */
 
101
/* Without strerror_r(), we can still provide a non-thread-safe
 
102
   version.  Maybe we are even lucky and the system's strerror() is
 
103
   already thread-safe.  */
 
104
 
 
105
int
 
106
system_strerror_r (int no, char *buf, size_t buflen)
 
107
{
 
108
  char *errstr = strerror (no);
 
109
 
 
110
  if (!errstr)
 
111
    {
 
112
      int saved_errno = errno;
 
113
 
 
114
      if (saved_errno != EINVAL)
 
115
        snprintf (buf, buflen, "strerror failed: %i\n", errno);
 
116
      return saved_errno;
 
117
    }
 
118
  else
 
119
    {
 
120
      size_t errstr_len = strlen (errstr) + 1;
 
121
      size_t cpy_len = errstr_len < buflen ? errstr_len : buflen;
 
122
      memcpy (buf, errstr, cpy_len);
 
123
      return cpy_len == errstr_len ? 0 : ERANGE;
 
124
    }
 
125
}
 
126
#endif
 
127
 
 
128
 
 
129
/* Return the error string for ERR in the user-supplied buffer BUF of
 
130
   size BUFLEN.  This function is, in contrast to gpg_strerror,
 
131
   thread-safe if a thread-safe strerror_r() function is provided by
 
132
   the system.  If the function succeeds, 0 is returned and BUF
 
133
   contains the string describing the error.  If the buffer was not
 
134
   large enough, ERANGE is returned and BUF contains as much of the
 
135
   beginning of the error string as fits into the buffer.  */
 
136
int
 
137
gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen)
 
138
{
 
139
  gpg_err_code_t code = gpg_err_code (err);
 
140
  const char *errstr;
 
141
  size_t errstr_len;
 
142
  size_t cpy_len;
 
143
 
 
144
  if (code & GPG_ERR_SYSTEM_ERROR)
 
145
    {
 
146
      int no = gpg_err_code_to_errno (code);
 
147
      if (no)
 
148
        {
 
149
          int system_err = system_strerror_r (no, buf, buflen);
 
150
 
 
151
          if (system_err != EINVAL)
 
152
            {
 
153
              if (buflen)
 
154
                buf[buflen - 1] = '\0';
 
155
              return system_err;
 
156
            }
 
157
        }
 
158
      code = GPG_ERR_UNKNOWN_ERRNO;
 
159
    }
 
160
 
 
161
  errstr = dgettext (PACKAGE, msgstr + msgidx[msgidxof (code)]);
 
162
  errstr_len = strlen (errstr) + 1;
 
163
  cpy_len = errstr_len < buflen ? errstr_len : buflen;
 
164
  memcpy (buf, errstr, cpy_len);
 
165
  if (buflen)
 
166
    buf[buflen - 1] = '\0';
 
167
 
 
168
  return cpy_len == errstr_len ? 0 : ERANGE;
 
169
}