Fix lookup of collation sequence value during regexp matching
[platform/upstream/glibc.git] / posix / confstr.c
1 /* Copyright (C) 1991,1996,1997,2000-2004,2009,2010 Free
2    Software Foundation, Inc.
3    This file is part of the GNU C Library.
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 <stddef.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <confstr.h>
25 #include "../version.h"
26
27 /* If BUF is not NULL and LEN > 0, fill in at most LEN - 1 bytes
28    of BUF with the value corresponding to NAME and zero-terminate BUF.
29    Return the number of bytes required to hold NAME's entire value.  */
30 size_t
31 confstr (name, buf, len)
32      int name;
33      char *buf;
34      size_t len;
35 {
36   const char *string = "";
37   size_t string_len = 1;
38
39   switch (name)
40     {
41     case _CS_PATH:
42       {
43         static const char cs_path[] = CS_PATH;
44         string = cs_path;
45         string_len = sizeof (cs_path);
46       }
47       break;
48
49     case _CS_V7_WIDTH_RESTRICTED_ENVS:
50       /* We have to return a newline-separated list of named of
51          programming environements in which the widths of blksize_t,
52          cc_t, mode_t, nfds_t, pid_t, ptrdiff_t, size_t, speed_t,
53          ssize_t, suseconds_t, tcflag_t, useconds_t, wchar_t, and
54          wint_t types are no greater than the width of type long.
55
56          Currently this means all environment which the system allows.  */
57       {
58         char restenvs[4 * sizeof "POSIX_V7_LPBIG_OFFBIG"];
59
60         string_len = 0;
61 #ifndef _POSIX_V7_ILP32_OFF32
62         if (__sysconf (_SC_V7_ILP32_OFF32) > 0)
63 #endif
64 #if !defined _POSIX_V7_ILP32_OFF32 || _POSIX_V7_ILP32_OFF32 > 0
65           {
66             memcpy (restenvs + string_len, "POSIX_V7_ILP32_OFF32",
67                     sizeof "POSIX_V7_ILP32_OFF32" - 1);
68             string_len += sizeof "POSIX_V7_ILP32_OFF32" - 1;
69           }
70 #endif
71 #ifndef _POSIX_V7_ILP32_OFFBIG
72         if (__sysconf (_SC_V7_ILP32_OFFBIG) > 0)
73 #endif
74 #if !defined _POSIX_V7_ILP32_OFFBIG || _POSIX_V7_ILP32_OFFBIG > 0
75           {
76             if (string_len)
77               restenvs[string_len++] = '\n';
78             memcpy (restenvs + string_len, "POSIX_V7_ILP32_OFFBIG",
79                     sizeof "POSIX_V7_ILP32_OFFBIG" - 1);
80             string_len += sizeof "POSIX_V7_ILP32_OFFBIG" - 1;
81           }
82 #endif
83 #ifndef _POSIX_V7_LP64_OFF64
84         if (__sysconf (_SC_V7_LP64_OFF64) > 0)
85 #endif
86 #if !defined _POSIX_V7_LP64_OFF64 || _POSIX_V7_LP64_OFF64 > 0
87           {
88             if (string_len)
89               restenvs[string_len++] = '\n';
90             memcpy (restenvs + string_len, "POSIX_V7_LP64_OFF64",
91                     sizeof "POSIX_V7_LP64_OFF64" - 1);
92             string_len += sizeof "POSIX_V7_LP64_OFF64" - 1;
93           }
94 #endif
95 #ifndef _POSIX_V7_LPBIG_OFFBIG
96         if (__sysconf (_SC_V7_LPBIG_OFFBIG) > 0)
97 #endif
98 #if !defined _POSIX_V7_LPBIG_OFFBIG || _POSIX_V7_LPBIG_OFFBIG > 0
99           {
100             if (string_len)
101               restenvs[string_len++] = '\n';
102             memcpy (restenvs + string_len, "POSIX_V7_LPBIG_OFFBIG",
103                     sizeof "POSIX_V7_LPBIG_OFFBIG" - 1);
104             string_len += sizeof "POSIX_V7_LPBIG_OFFBIG" - 1;
105           }
106 #endif
107         restenvs[string_len++] = '\0';
108         string = restenvs;
109       }
110       break;
111
112     case _CS_V6_WIDTH_RESTRICTED_ENVS:
113       /* We have to return a newline-separated list of named of
114          programming environements in which the widths of blksize_t,
115          cc_t, mode_t, nfds_t, pid_t, ptrdiff_t, size_t, speed_t,
116          ssize_t, suseconds_t, tcflag_t, useconds_t, wchar_t, and
117          wint_t types are no greater than the width of type long.
118
119          Currently this means all environment which the system allows.  */
120       {
121         char restenvs[4 * sizeof "POSIX_V6_LPBIG_OFFBIG"];
122
123         string_len = 0;
124 #ifndef _POSIX_V6_ILP32_OFF32
125         if (__sysconf (_SC_V6_ILP32_OFF32) > 0)
126 #endif
127 #if !defined _POSIX_V6_ILP32_OFF32 || _POSIX_V6_ILP32_OFF32 > 0
128           {
129             memcpy (restenvs + string_len, "POSIX_V6_ILP32_OFF32",
130                     sizeof "POSIX_V6_ILP32_OFF32" - 1);
131             string_len += sizeof "POSIX_V6_ILP32_OFF32" - 1;
132           }
133 #endif
134 #ifndef _POSIX_V6_ILP32_OFFBIG
135         if (__sysconf (_SC_V6_ILP32_OFFBIG) > 0)
136 #endif
137 #if !defined _POSIX_V6_ILP32_OFFBIG || _POSIX_V6_ILP32_OFFBIG > 0
138           {
139             if (string_len)
140               restenvs[string_len++] = '\n';
141             memcpy (restenvs + string_len, "POSIX_V6_ILP32_OFFBIG",
142                     sizeof "POSIX_V6_ILP32_OFFBIG" - 1);
143             string_len += sizeof "POSIX_V6_ILP32_OFFBIG" - 1;
144           }
145 #endif
146 #ifndef _POSIX_V6_LP64_OFF64
147         if (__sysconf (_SC_V6_LP64_OFF64) > 0)
148 #endif
149 #if !defined _POSIX_V6_LP64_OFF64 || _POSIX_V6_LP64_OFF64 > 0
150           {
151             if (string_len)
152               restenvs[string_len++] = '\n';
153             memcpy (restenvs + string_len, "POSIX_V6_LP64_OFF64",
154                     sizeof "POSIX_V6_LP64_OFF64" - 1);
155             string_len += sizeof "POSIX_V6_LP64_OFF64" - 1;
156           }
157 #endif
158 #ifndef _POSIX_V6_LPBIG_OFFBIG
159         if (__sysconf (_SC_V6_LPBIG_OFFBIG) > 0)
160 #endif
161 #if !defined _POSIX_V6_LPBIG_OFFBIG || _POSIX_V6_LPBIG_OFFBIG > 0
162           {
163             if (string_len)
164               restenvs[string_len++] = '\n';
165             memcpy (restenvs + string_len, "POSIX_V6_LPBIG_OFFBIG",
166                     sizeof "POSIX_V6_LPBIG_OFFBIG" - 1);
167             string_len += sizeof "POSIX_V6_LPBIG_OFFBIG" - 1;
168           }
169 #endif
170         restenvs[string_len++] = '\0';
171         string = restenvs;
172       }
173       break;
174
175     case _CS_V5_WIDTH_RESTRICTED_ENVS:
176       /* We have to return a newline-separated list of named of
177          programming environements in which the widths of blksize_t,
178          cc_t, mode_t, nfds_t, pid_t, ptrdiff_t, size_t, speed_t,
179          ssize_t, suseconds_t, tcflag_t, useconds_t, wchar_t, and
180          wint_t types are no greater than the width of type long.
181
182          Currently this means all environment which the system allows.  */
183       {
184         char restenvs[4 * sizeof "XBS5_LPBIG_OFFBIG"];
185
186         string_len = 0;
187 #ifndef _XBS5_ILP32_OFF32
188         if (__sysconf (_SC_XBS5_ILP32_OFF32) > 0)
189 #endif
190 #if !defined _XBS5_ILP32_OFF32 || _XBS5_ILP32_OFF32 > 0
191           {
192             memcpy (restenvs + string_len, "XBS5_ILP32_OFF32",
193                     sizeof "XBS5_ILP32_OFF32" - 1);
194             string_len += sizeof "XBS5_ILP32_OFF32" - 1;
195           }
196 #endif
197 #ifndef _XBS5_ILP32_OFFBIG
198         if (__sysconf (_SC_XBS5_ILP32_OFFBIG) > 0)
199 #endif
200 #if !defined _XBS5_ILP32_OFFBIG || _XBS5_ILP32_OFFBIG > 0
201           {
202             if (string_len)
203               restenvs[string_len++] = '\n';
204             memcpy (restenvs + string_len, "XBS5_ILP32_OFFBIG",
205                     sizeof "XBS5_ILP32_OFFBIG" - 1);
206             string_len += sizeof "XBS5_ILP32_OFFBIG" - 1;
207           }
208 #endif
209 #ifndef _XBS5_LP64_OFF64
210         if (__sysconf (_SC_XBS5_LP64_OFF64) > 0)
211 #endif
212 #if !defined _XBS5_LP64_OFF64 || _XBS5_LP64_OFF64 > 0
213           {
214             if (string_len)
215               restenvs[string_len++] = '\n';
216             memcpy (restenvs + string_len, "XBS5_LP64_OFF64",
217                     sizeof "XBS5_LP64_OFF64" - 1);
218             string_len += sizeof "XBS5_LP64_OFF64" - 1;
219           }
220 #endif
221 #ifndef _XBS5_LPBIG_OFFBIG
222         if (__sysconf (_SC_XBS5_LPBIG_OFFBIG) > 0)
223 #endif
224 #if !defined _XBS5_LPBIG_OFFBIG || _XBS5_LPBIG_OFFBIG > 0
225           {
226             if (string_len)
227               restenvs[string_len++] = '\n';
228             memcpy (restenvs + string_len, "XBS5_LPBIG_OFFBIG",
229                     sizeof "XBS5_LPBIG_OFFBIG" - 1);
230             string_len += sizeof "XBS5_LPBIG_OFFBIG" - 1;
231           }
232 #endif
233         restenvs[string_len++] = '\0';
234         string = restenvs;
235       }
236       break;
237
238     case _CS_XBS5_ILP32_OFF32_CFLAGS:
239     case _CS_POSIX_V6_ILP32_OFF32_CFLAGS:
240     case _CS_POSIX_V7_ILP32_OFF32_CFLAGS:
241 #ifdef __ILP32_OFF32_CFLAGS
242 # if _POSIX_V7_ILP32_OFF32 == -1
243 #  error "__ILP32_OFF32_CFLAGS should not be defined"
244 # elif !defined _POSIX_V7_ILP32_OFF32
245       if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
246         break;
247 # endif
248       string = __ILP32_OFF32_CFLAGS;
249       string_len = sizeof (__ILP32_OFF32_CFLAGS);
250 #endif
251       break;
252
253     case _CS_XBS5_ILP32_OFFBIG_CFLAGS:
254     case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS:
255     case _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS:
256 #ifdef __ILP32_OFFBIG_CFLAGS
257 # if _POSIX_V7_ILP32_OFFBIG == -1
258 #  error "__ILP32_OFFBIG_CFLAGS should not be defined"
259 # elif !defined _POSIX_V7_ILP32_OFFBIG
260       if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
261         break;
262 # endif
263       string = __ILP32_OFFBIG_CFLAGS;
264       string_len = sizeof (__ILP32_OFFBIG_CFLAGS);
265 #endif
266       break;
267
268     case _CS_XBS5_LP64_OFF64_CFLAGS:
269     case _CS_POSIX_V6_LP64_OFF64_CFLAGS:
270     case _CS_POSIX_V7_LP64_OFF64_CFLAGS:
271 #ifdef __LP64_OFF64_CFLAGS
272 # if _POSIX_V7_LP64_OFF64 == -1
273 #  error "__LP64_OFF64_CFLAGS should not be defined"
274 # elif !defined _POSIX_V7_LP64_OFF64
275       if (__sysconf (_SC_V7_LP64_OFF64) < 0)
276         break;
277 # endif
278       string = __LP64_OFF64_CFLAGS;
279       string_len = sizeof (__LP64_OFF64_CFLAGS);
280 #endif
281       break;
282
283     case _CS_XBS5_ILP32_OFF32_LDFLAGS:
284     case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS:
285     case _CS_POSIX_V7_ILP32_OFF32_LDFLAGS:
286 #ifdef __ILP32_OFF32_LDFLAGS
287 # if _POSIX_V7_ILP32_OFF32 == -1
288 #  error "__ILP32_OFF32_LDFLAGS should not be defined"
289 # elif !defined _POSIX_V7_ILP32_OFF32
290       if (__sysconf (_SC_V7_ILP32_OFF32) < 0)
291         break;
292 # endif
293       string = __ILP32_OFF32_LDFLAGS;
294       string_len = sizeof (__ILP32_OFF32_LDFLAGS);
295 #endif
296       break;
297
298     case _CS_XBS5_ILP32_OFFBIG_LDFLAGS:
299     case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS:
300     case _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS:
301 #ifdef __ILP32_OFFBIG_LDFLAGS
302 # if _POSIX_V7_ILP32_OFFBIG == -1
303 #  error "__ILP32_OFFBIG_LDFLAGS should not be defined"
304 # elif !defined _POSIX_V7_ILP32_OFFBIG
305       if (__sysconf (_SC_V7_ILP32_OFFBIG) < 0)
306         break;
307 # endif
308       string = __ILP32_OFFBIG_LDFLAGS;
309       string_len = sizeof (__ILP32_OFFBIG_LDFLAGS);
310 #endif
311       break;
312
313     case _CS_XBS5_LP64_OFF64_LDFLAGS:
314     case _CS_POSIX_V6_LP64_OFF64_LDFLAGS:
315     case _CS_POSIX_V7_LP64_OFF64_LDFLAGS:
316 #ifdef __LP64_OFF64_LDFLAGS
317 # if _POSIX_V7_LP64_OFF64 == -1
318 #  error "__LP64_OFF64_LDFLAGS should not be defined"
319 # elif !defined _POSIX_V7_LP64_OFF64
320       if (__sysconf (_SC_V7_LP64_OFF64) < 0)
321         break;
322 # endif
323       string = __LP64_OFF64_LDFLAGS;
324       string_len = sizeof (__LP64_OFF64_LDFLAGS);
325 #endif
326       break;
327
328     case _CS_LFS_CFLAGS:
329     case _CS_LFS_LINTFLAGS:
330 #if _POSIX_V6_ILP32_OFF32 == 1 && _POSIX_V6_ILP32_OFFBIG == 1
331 # define __LFS_CFLAGS "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
332       /* Signal that we want the new ABI.  */
333       string = __LFS_CFLAGS;
334       string_len = sizeof (__LFS_CFLAGS);
335 #endif
336       break;
337
338     case _CS_LFS_LDFLAGS:
339     case _CS_LFS_LIBS:
340       /* No special libraries or linker flags needed.  */
341       break;
342
343     case _CS_LFS64_CFLAGS:
344     case _CS_LFS64_LINTFLAGS:
345 #define __LFS64_CFLAGS "-D_LARGEFILE64_SOURCE"
346       string = __LFS64_CFLAGS;
347       string_len = sizeof (__LFS64_CFLAGS);
348       break;
349
350     case _CS_LFS64_LDFLAGS:
351     case _CS_LFS64_LIBS:
352       /* No special libraries or linker flags needed.  */
353       break;
354
355     case _CS_XBS5_ILP32_OFF32_LIBS:
356     case _CS_XBS5_ILP32_OFF32_LINTFLAGS:
357     case _CS_XBS5_ILP32_OFFBIG_LIBS:
358     case _CS_XBS5_ILP32_OFFBIG_LINTFLAGS:
359     case _CS_XBS5_LP64_OFF64_LIBS:
360     case _CS_XBS5_LP64_OFF64_LINTFLAGS:
361     case _CS_XBS5_LPBIG_OFFBIG_CFLAGS:
362     case _CS_XBS5_LPBIG_OFFBIG_LDFLAGS:
363     case _CS_XBS5_LPBIG_OFFBIG_LIBS:
364     case _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS:
365
366     case _CS_POSIX_V6_ILP32_OFF32_LIBS:
367     case _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS:
368     case _CS_POSIX_V6_ILP32_OFFBIG_LIBS:
369     case _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS:
370     case _CS_POSIX_V6_LP64_OFF64_LIBS:
371     case _CS_POSIX_V6_LP64_OFF64_LINTFLAGS:
372     case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS:
373     case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS:
374     case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS:
375     case _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS:
376
377     case _CS_POSIX_V7_ILP32_OFF32_LIBS:
378     case _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS:
379     case _CS_POSIX_V7_ILP32_OFFBIG_LIBS:
380     case _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS:
381     case _CS_POSIX_V7_LP64_OFF64_LIBS:
382     case _CS_POSIX_V7_LP64_OFF64_LINTFLAGS:
383     case _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS:
384     case _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS:
385     case _CS_POSIX_V7_LPBIG_OFFBIG_LIBS:
386     case _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS:
387       /* GNU libc does not require special actions to use LFS functions.  */
388       break;
389
390     case _CS_GNU_LIBC_VERSION:
391       string = "glibc " VERSION;
392       string_len = sizeof ("glibc " VERSION);
393       break;
394
395     case _CS_GNU_LIBPTHREAD_VERSION:
396 #ifdef LIBPTHREAD_VERSION
397       string = LIBPTHREAD_VERSION;
398       string_len = sizeof LIBPTHREAD_VERSION;
399       break;
400 #else
401       /* No thread library.  */
402       __set_errno (EINVAL);
403       return 0;
404 #endif
405
406     case _CS_V6_ENV:
407     case _CS_V7_ENV:
408       /* Maybe something else is needed in future.  */
409       string = "POSIXLY_CORRECT=1";
410       string_len = sizeof ("POSIXLY_CORRECT=1");
411       break;
412
413     default:
414       __set_errno (EINVAL);
415       return 0;
416     }
417
418   if (len > 0 && buf != NULL)
419     {
420       if (string_len <= len)
421         memcpy (buf, string, string_len);
422       else
423         {
424           memcpy (buf, string, len - 1);
425           buf[len - 1] = '\0';
426         }
427     }
428   return string_len;
429 }
430 libc_hidden_def (confstr)