2004-11-29 Roland McGrath <roland@redhat.com>
[platform/upstream/glibc.git] / posix / confstr.c
1 /* Copyright (C) 1991, 1996, 1997, 2000-2002, 2003, 2004
2    Free 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_V6_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_V6_LPBIG_OFFBIG"];
59
60         string_len = 0;
61 #ifndef _POSIX_V6_ILP32_OFF32
62         if (__sysconf (_SC_V6_ILP32_OFF32) > 0)
63 #endif
64 #if !defined _POSIX_V6_ILP32_OFF32 || _POSIX_V6_ILP32_OFF32 > 0
65           {
66             memcpy (restenvs + string_len, "_POSIX_V6_ILP32_OFF32",
67                     sizeof "_POSIX_V6_ILP32_OFF32" - 1);
68             string_len += sizeof "_POSIX_V6_ILP32_OFF32" - 1;
69           }
70 #endif
71 #ifndef _POSIX_V6_ILP32_OFFBIG
72         if (__sysconf (_SC_V6_ILP32_OFFBIG) > 0)
73 #endif
74 #if !defined _POSIX_V6_ILP32_OFFBIG || _POSIX_V6_ILP32_OFFBIG > 0
75           {
76             if (string_len)
77               restenvs[string_len++] = '\n';
78             memcpy (restenvs + string_len, "_POSIX_V6_ILP32_OFFBIG",
79                     sizeof "_POSIX_V6_ILP32_OFFBIG" - 1);
80             string_len += sizeof "_POSIX_V6_ILP32_OFFBIG" - 1;
81           }
82 #endif
83 #ifndef _POSIX_V6_LP64_OFF64
84         if (__sysconf (_SC_V6_LP64_OFF64) > 0)
85 #endif
86 #if !defined _POSIX_V6_LP64_OFF64 || _POSIX_V6_LP64_OFF64 > 0
87           {
88             if (string_len)
89               restenvs[string_len++] = '\n';
90             memcpy (restenvs + string_len, "_POSIX_V6_LP64_OFF64",
91                     sizeof "_POSIX_V6_LP64_OFF64" - 1);
92             string_len += sizeof "_POSIX_V6_LP64_OFF64" - 1;
93           }
94 #endif
95 #ifndef _POSIX_V6_LPBIG_OFFBIG
96         if (__sysconf (_SC_V6_LPBIG_OFFBIG) > 0)
97 #endif
98 #if !defined _POSIX_V6_LPBIG_OFFBIG || _POSIX_V6_LPBIG_OFFBIG > 0
99           {
100             if (string_len)
101               restenvs[string_len++] = '\n';
102             memcpy (restenvs + string_len, "_POSIX_V6_LPBIG_OFFBIG",
103                     sizeof "_POSIX_V6_LPBIG_OFFBIG" - 1);
104             string_len += sizeof "_POSIX_V6_LPBIG_OFFBIG" - 1;
105           }
106 #endif
107         restenvs[string_len++] = '\0';
108         string = restenvs;
109       }
110       break;
111
112     case _CS_XBS5_ILP32_OFF32_CFLAGS:
113     case _CS_POSIX_V6_ILP32_OFF32_CFLAGS:
114 #ifdef __ILP32_OFF32_CFLAGS
115 # if _POSIX_V6_ILP32_OFF32 == -1
116 #  error __ILP32_OFF32_CFLAGS should not be defined
117 # elif !defined _POSIX_V6_ILP32_OFF32
118       if (__sysconf (_SC_V6_ILP32_OFF32) < 0)
119         break;
120 # endif
121       string = __ILP32_OFF32_CFLAGS;
122       string_len = sizeof (__ILP32_OFF32_CFLAGS);
123 #endif
124       break;
125
126     case _CS_XBS5_ILP32_OFFBIG_CFLAGS:
127     case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS:
128 #ifdef __ILP32_OFFBIG_CFLAGS
129 # if _POSIX_V6_ILP32_OFFBIG == -1
130 #  error __ILP32_OFFBIG_CFLAGS should not be defined
131 # elif !defined _POSIX_V6_ILP32_OFFBIG
132       if (__sysconf (_SC_V6_ILP32_OFFBIG) < 0)
133         break;
134 # endif
135       string = __ILP32_OFFBIG_CFLAGS;
136       string_len = sizeof (__ILP32_OFFBIG_CFLAGS);
137 #endif
138       break;
139
140     case _CS_XBS5_LP64_OFF64_CFLAGS:
141     case _CS_POSIX_V6_LP64_OFF64_CFLAGS:
142 #ifdef __LP64_OFF64_CFLAGS
143 # if _POSIX_V6_LP64_OFF64 == -1
144 #  error __LP64_OFF64_CFLAGS should not be defined
145 # elif !defined _POSIX_V6_LP64_OFF64
146       if (__sysconf (_SC_V6_LP64_OFF64) < 0)
147         break;
148 # endif
149       string = __LP64_OFF64_CFLAGS;
150       string_len = sizeof (__LP64_OFF64_CFLAGS);
151 #endif
152       break;
153
154     case _CS_XBS5_ILP32_OFF32_LDFLAGS:
155     case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS:
156 #ifdef __ILP32_OFF32_LDFLAGS
157 # if _POSIX_V6_ILP32_OFF32 == -1
158 #  error __ILP32_OFF32_LDFLAGS should not be defined
159 # elif !defined _POSIX_V6_ILP32_OFF32
160       if (__sysconf (_SC_V6_ILP32_OFF32) < 0)
161         break;
162 # endif
163       string = __ILP32_OFF32_LDFLAGS;
164       string_len = sizeof (__ILP32_OFF32_LDFLAGS);
165 #endif
166       break;
167
168     case _CS_XBS5_ILP32_OFFBIG_LDFLAGS:
169     case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS:
170 #ifdef __ILP32_OFFBIG_LDFLAGS
171 # if _POSIX_V6_ILP32_OFFBIG == -1
172 #  error __ILP32_OFFBIG_LDFLAGS should not be defined
173 # elif !defined _POSIX_V6_ILP32_OFFBIG
174       if (__sysconf (_SC_V6_ILP32_OFFBIG) < 0)
175         break;
176 # endif
177       string = __ILP32_OFFBIG_LDFLAGS;
178       string_len = sizeof (__ILP32_OFFBIG_LDFLAGS);
179 #endif
180       break;
181
182     case _CS_XBS5_LP64_OFF64_LDFLAGS:
183     case _CS_POSIX_V6_LP64_OFF64_LDFLAGS:
184 #ifdef __LP64_OFF64_LDFLAGS
185 # if _POSIX_V6_LP64_OFF64 == -1
186 #  error __LP64_OFF64_LDFLAGS should not be defined
187 # elif !defined _POSIX_V6_LP64_OFF64
188       if (__sysconf (_SC_V6_LP64_OFF64) < 0)
189         break;
190 # endif
191       string = __LP64_OFF64_LDFLAGS;
192       string_len = sizeof (__LP64_OFF64_LDFLAGS);
193 #endif
194       break;
195
196     case _CS_LFS_CFLAGS:
197     case _CS_LFS_LINTFLAGS:
198 #if _POSIX_V6_ILP32_OFF32 == 1 && _POSIX_V6_ILP32_OFFBIG == 1
199 # define __LFS_CFLAGS "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
200       /* Signal that we want the new ABI.  */
201       string = __LFS_CFLAGS;
202       string_len = sizeof (__LFS_CFLAGS);
203 #endif
204       break;
205
206     case _CS_LFS_LDFLAGS:
207     case _CS_LFS_LIBS:
208       /* No special libraries or linker flags needed.  */
209       break;
210
211     case _CS_LFS64_CFLAGS:
212     case _CS_LFS64_LINTFLAGS:
213 #define __LFS64_CFLAGS "-D_LARGEFILE64_SOURCE"
214       string = __LFS64_CFLAGS;
215       string_len = sizeof (__LFS64_CFLAGS);
216       break;
217
218     case _CS_LFS64_LDFLAGS:
219     case _CS_LFS64_LIBS:
220       /* No special libraries or linker flags needed.  */
221       break;
222
223     case _CS_XBS5_ILP32_OFF32_LIBS:
224     case _CS_XBS5_ILP32_OFF32_LINTFLAGS:
225     case _CS_XBS5_ILP32_OFFBIG_LIBS:
226     case _CS_XBS5_ILP32_OFFBIG_LINTFLAGS:
227     case _CS_XBS5_LP64_OFF64_LIBS:
228     case _CS_XBS5_LP64_OFF64_LINTFLAGS:
229     case _CS_XBS5_LPBIG_OFFBIG_CFLAGS:
230     case _CS_XBS5_LPBIG_OFFBIG_LDFLAGS:
231     case _CS_XBS5_LPBIG_OFFBIG_LIBS:
232     case _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS:
233
234     case _CS_POSIX_V6_ILP32_OFF32_LIBS:
235     case _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS:
236     case _CS_POSIX_V6_ILP32_OFFBIG_LIBS:
237     case _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS:
238     case _CS_POSIX_V6_LP64_OFF64_LIBS:
239     case _CS_POSIX_V6_LP64_OFF64_LINTFLAGS:
240     case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS:
241     case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS:
242     case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS:
243     case _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS:
244       /* GNU libc does not require special actions to use LFS functions.  */
245       break;
246
247     case _CS_GNU_LIBC_VERSION:
248       string = "glibc " VERSION;
249       string_len = sizeof ("glibc " VERSION);
250       break;
251
252     case _CS_GNU_LIBPTHREAD_VERSION:
253 #ifdef LIBPTHREAD_VERSION
254       string = LIBPTHREAD_VERSION;
255       string_len = sizeof LIBPTHREAD_VERSION;
256       break;
257 #else
258       /* No thread library.  */
259       __set_errno (EINVAL);
260       return 0;
261 #endif
262
263     default:
264       __set_errno (EINVAL);
265       return 0;
266     }
267
268   if (len > 0 && buf != NULL)
269     {
270       if (string_len <= len)
271         memcpy (buf, string, string_len);
272       else
273         {
274           memcpy (buf, string, len - 1);
275           buf[len - 1] = '\0';
276         }
277     }
278   return string_len;
279 }
280 libc_hidden_def (confstr)