source: trunk/libs/newlib/src/newlib/libc/sys/linux/net/getXXbyYY_r.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 8.2 KB
Line 
1/* Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library; if not, write to the Free
17   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18   02111-1307 USA.  */
19
20#include <assert.h>
21#include <errno.h>
22#include <stdbool.h>
23#include "nsswitch.h"
24#ifdef USE_NSCD
25# include <nscd/nscd_proto.h>
26#endif
27#ifdef NEED__RES_HCONF
28# include "res_hconf.h"
29#endif
30#ifdef NEED__RES
31# include <resolv.h>
32#endif
33/*******************************************************************\
34|* Here we assume several symbols to be defined:                   *|
35|*                                                                 *|
36|* LOOKUP_TYPE   - the return type of the function                 *|
37|*                                                                 *|
38|* FUNCTION_NAME - name of the non-reentrant function              *|
39|*                                                                 *|
40|* DATABASE_NAME - name of the database the function accesses      *|
41|*                 (e.g., host, services, ...)                     *|
42|*                                                                 *|
43|* ADD_PARAMS    - additional parameter, can vary in number        *|
44|*                                                                 *|
45|* ADD_VARIABLES - names of additional parameter                   *|
46|*                                                                 *|
47|* Optionally the following vars can be defined:                   *|
48|*                                                                 *|
49|* NEED_H_ERRNO  - an extra parameter will be passed to point to   *|
50|*                 the global `h_errno' variable.                  *|
51|*                                                                 *|
52|* NEED__RES     - the global _res variable might be used so we    *|
53|*                 will have to initialize it if necessary         *|
54|*                                                                 *|
55|* PREPROCESS    - code run before anything else                   *|
56|*                                                                 *|
57|* POSTPROCESS   - code run after the lookup                       *|
58|*                                                                 *|
59\*******************************************************************/
60
61/* To make the real sources a bit prettier.  */
62#define REENTRANT_NAME APPEND_R (FUNCTION_NAME)
63#define APPEND_R(name) APPEND_R1 (name)
64#define APPEND_R1(name) name##_r
65#define INTERNAL(name) INTERNAL1 (name)
66#define INTERNAL1(name) __##name
67#define NEW(name) NEW1 (name)
68#define NEW1(name) __new_##name
69
70#ifdef USE_NSCD
71# define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
72# define ADD_NSCD(name) ADD_NSCD1 (name)
73# define ADD_NSCD1(name) __nscd_##name
74# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
75# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
76# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
77#endif
78
79#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
80#define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME)
81#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
82#define STRINGIZE(name) STRINGIZE1 (name)
83#define STRINGIZE1(name) #name
84
85#ifndef DB_LOOKUP_FCT
86# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
87# define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
88# define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
89#endif
90
91/* Sometimes we need to store error codes in the `h_errno' variable.  */
92#ifdef NEED_H_ERRNO
93# define H_ERRNO_PARM , int *h_errnop
94# define H_ERRNO_VAR , h_errnop
95# define H_ERRNO_VAR_P h_errnop
96#else
97# define H_ERRNO_PARM
98# define H_ERRNO_VAR
99# define H_ERRNO_VAR_P NULL
100#endif
101
102#ifdef HAVE_AF
103# define AF_VAL af
104#else
105# define AF_VAL AF_INET
106#endif
107
108/* Type of the lookup function we need here.  */
109typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
110                                            size_t, int * H_ERRNO_PARM);
111
112/* The lookup function for the first entry of this service.  */
113extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp)
114     internal_function;
115libc_hidden_proto (DB_LOOKUP_FCT)
116
117
118int
119INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
120                           size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM)
121{
122  static service_user *startp;
123  static lookup_function start_fct;
124  service_user *nip;
125  union
126  {
127    lookup_function l;
128    void *ptr;
129  } fct;
130
131  int no_more;
132  enum nss_status status = NSS_STATUS_UNAVAIL;
133#ifdef USE_NSCD
134  int nscd_status;
135#endif
136#ifdef NEED_H_ERRNO
137  bool any_service = false;
138#endif
139
140#ifdef PREPROCESS
141  PREPROCESS;
142#endif
143
144#ifdef HANDLE_DIGITS_DOTS
145  switch (__nss_hostname_digits_dots (name, resbuf, &buffer, NULL,
146                                      buflen, result, &status, AF_VAL,
147                                      H_ERRNO_VAR_P))
148    {
149    case -1:
150      return errno;
151    case 1:
152      goto done;
153    }
154#endif
155
156#ifdef USE_NSCD
157  if (NOT_USENSCD_NAME > 0 && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
158    NOT_USENSCD_NAME = 0;
159
160  if (!NOT_USENSCD_NAME)
161    {
162      nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
163                               H_ERRNO_VAR);
164      if (nscd_status >= 0)
165        return nscd_status;
166    }
167#endif
168
169  if (startp == NULL)
170    {
171      no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, &fct.ptr);
172      if (no_more)
173        startp = (service_user *) -1l;
174      else
175        {
176          startp = nip;
177          start_fct = fct.l;
178
179#ifdef NEED__RES
180          /* The resolver code will really be used so we have to
181             initialize it.  */
182          if (__res_maybe_init (&_res, 0) == -1)
183            {
184              *h_errnop = NETDB_INTERNAL;
185              *result = NULL;
186              return errno;
187            }
188#endif /* need _res */
189#ifdef NEED__RES_HCONF
190          if (!_res_hconf.initialized)
191            _res_hconf_init ();
192#endif /* need _res_hconf */
193        }
194    }
195  else
196    {
197      fct.l = start_fct;
198      no_more = (nip = startp) == (service_user *) -1l;
199    }
200
201  while (no_more == 0)
202    {
203#ifdef NEED_H_ERRNO
204      any_service = true;
205#endif
206
207      status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen,
208                                    &errno H_ERRNO_VAR));
209
210      /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
211         provided buffer is too small.  In this case we should give
212         the user the possibility to enlarge the buffer and we should
213         not simply go on with the next service (even if the TRYAGAIN
214         action tells us so).  */
215      if (status == NSS_STATUS_TRYAGAIN
216#ifdef NEED_H_ERRNO
217          && *h_errnop == NETDB_INTERNAL
218#endif
219          && errno == ERANGE)
220        break;
221
222      no_more = __nss_next (&nip, REENTRANT_NAME_STRING,
223                            &fct.ptr, status, 0);
224    }
225
226#ifdef HANDLE_DIGITS_DOTS
227done:
228#endif
229  *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
230#ifdef NEED_H_ERRNO
231  if (status != NSS_STATUS_SUCCESS && ! any_service)
232    /* We were not able to use any service.  */
233    *h_errnop = NO_RECOVERY;
234#endif
235#ifdef POSTPROCESS
236  POSTPROCESS;
237#endif
238
239  int res;
240  if (status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
241    res = 0;
242  /* Don't pass back ERANGE if this is not for a too-small buffer.  */
243  else if (errno == ERANGE && status != NSS_STATUS_TRYAGAIN)
244    res = EINVAL;
245#ifdef NEED_H_ERRNO
246  /* These functions only set errno if h_errno is NETDB_INTERNAL.  */
247  else if (status == NSS_STATUS_TRYAGAIN && *h_errnop != NETDB_INTERNAL)
248    res = EAGAIN;
249#endif
250  else
251    return errno;
252
253  __set_errno (res);
254  return res;
255}
256
257
258#include <shlib-compat.h>
259#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
260#define OLD(name) OLD1 (name)
261#define OLD1(name) __old_##name
262
263int
264attribute_compat_text_section
265OLD (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
266                      size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM)
267{
268  int ret = INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, resbuf, buffer,
269                                       buflen, result H_ERRNO_VAR);
270
271  if (ret != 0 || result == NULL)
272    ret = -1;
273
274  return ret;
275}
276
277#define do_symbol_version(real, name, version) \
278  compat_symbol (libc, real, name, version)
279do_symbol_version (OLD (REENTRANT_NAME), REENTRANT_NAME, GLIBC_2_0);
280#endif
281
282/* As INTERNAL (REENTRANT_NAME) may be hidden, we need an alias
283   in between so that the REENTRANT_NAME@@GLIBC_2.1.2 is not
284   hidden too.  */
285strong_alias (INTERNAL (REENTRANT_NAME), NEW (REENTRANT_NAME));
286
287#define do_default_symbol_version(real, name, version) \
288  versioned_symbol (libc, real, name, version)
289do_default_symbol_version (NEW (REENTRANT_NAME),
290                           REENTRANT_NAME, GLIBC_2_1_2);
291
292static_link_warning (REENTRANT_NAME)
Note: See TracBrowser for help on using the repository browser.