OSDN Git Service

* Makefile.in (CYGWIN_BINS): Add getconf.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / utils / getconf.c
1 /*-
2  * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
3  * Copyright (c) 2011 Red Hat, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by J.T. Conklin.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <error.h>
32 #include <errno.h>
33 #include <limits.h>
34 #include <locale.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <string.h>
39
40 struct conf_variable
41 {
42   const char *name;
43   enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT } type;
44   long long value;
45 };
46
47 static const struct conf_variable conf_table[] =
48 {
49   /* Symbolic constants from confstr() */
50   { "PATH",                             CONFSTR,        _CS_PATH        },
51   { "POSIX_V7_ILP32_OFF32_CFLAGS",      CONFSTR,        _CS_POSIX_V7_ILP32_OFF32_CFLAGS },
52   { "POSIX_V7_ILP32_OFF32_LDFLAGS",     CONFSTR,        _CS_POSIX_V7_ILP32_OFF32_LDFLAGS        },
53   { "POSIX_V7_ILP32_OFF32_LIBS",        CONFSTR,        _CS_POSIX_V7_ILP32_OFF32_LIBS   },
54   { "POSIX_V7_ILP32_OFFBIG_CFLAGS",     CONFSTR,        _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS        },
55   { "POSIX_V7_ILP32_OFFBIG_LDFLAGS",    CONFSTR,        _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS       },
56   { "POSIX_V7_ILP32_OFFBIG_LIBS",       CONFSTR,        _CS_POSIX_V7_ILP32_OFFBIG_LIBS  },
57   { "POSIX_V7_LP64_OFF64_CFLAGS",       CONFSTR,        _CS_POSIX_V7_LP64_OFF64_CFLAGS  },
58   { "POSIX_V7_LP64_OFF64_LDFLAGS",      CONFSTR,        _CS_POSIX_V7_LP64_OFF64_LDFLAGS },
59   { "POSIX_V7_LP64_OFF64_LIBS",         CONFSTR,        _CS_POSIX_V7_LP64_OFF64_LIBS    },
60   { "POSIX_V7_LPBIG_OFFBIG_CFLAGS",     CONFSTR,        _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS        },
61   { "POSIX_V7_LPBIG_OFFBIG_LDFLAGS",    CONFSTR,        _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS       },
62   { "POSIX_V7_LPBIG_OFFBIG_LIBS",       CONFSTR,        _CS_POSIX_V7_LPBIG_OFFBIG_LIBS  },
63   { "POSIX_V7_THREADS_CFLAGS",          CONFSTR,        _CS_POSIX_V7_THREADS_CFLAGS     },
64   { "POSIX_V7_THREADS_LDFLAGS",         CONFSTR,        _CS_POSIX_V7_THREADS_LDFLAGS    },
65   { "POSIX_V7_WIDTH_RESTRICTED_ENVS",   CONFSTR,        _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS      },
66   { "POSIX_V6_ILP32_OFF32_CFLAGS",      CONFSTR,        _CS_POSIX_V6_ILP32_OFF32_CFLAGS },
67   { "POSIX_V6_ILP32_OFF32_LDFLAGS",     CONFSTR,        _CS_POSIX_V6_ILP32_OFF32_LDFLAGS        },
68   { "POSIX_V6_ILP32_OFF32_LIBS",        CONFSTR,        _CS_POSIX_V6_ILP32_OFF32_LIBS   },
69   { "POSIX_V6_ILP32_OFFBIG_CFLAGS",     CONFSTR,        _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS        },
70   { "POSIX_V6_ILP32_OFFBIG_LDFLAGS",    CONFSTR,        _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS       },
71   { "POSIX_V6_ILP32_OFFBIG_LIBS",       CONFSTR,        _CS_POSIX_V6_ILP32_OFFBIG_LIBS  },
72   { "POSIX_V6_LP64_OFF64_CFLAGS",       CONFSTR,        _CS_POSIX_V6_LP64_OFF64_CFLAGS  },
73   { "POSIX_V6_LP64_OFF64_LDFLAGS",      CONFSTR,        _CS_POSIX_V6_LP64_OFF64_LDFLAGS },
74   { "POSIX_V6_LP64_OFF64_LIBS",         CONFSTR,        _CS_POSIX_V6_LP64_OFF64_LIBS    },
75   { "POSIX_V6_LPBIG_OFFBIG_CFLAGS",     CONFSTR,        _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS        },
76   { "POSIX_V6_LPBIG_OFFBIG_LDFLAGS",    CONFSTR,        _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS       },
77   { "POSIX_V6_LPBIG_OFFBIG_LIBS",       CONFSTR,        _CS_POSIX_V6_LPBIG_OFFBIG_LIBS  },
78   { "POSIX_V6_WIDTH_RESTRICTED_ENVS",   CONFSTR,        _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS      },
79   { "XBS5_ILP32_OFF32_CFLAGS",          CONFSTR,        _CS_XBS5_ILP32_OFF32_CFLAGS     },
80   { "XBS5_ILP32_OFF32_LDFLAGS",         CONFSTR,        _CS_XBS5_ILP32_OFF32_LDFLAGS    },
81   { "XBS5_ILP32_OFF32_LIBS",            CONFSTR,        _CS_XBS5_ILP32_OFF32_LIBS       },
82   { "XBS5_ILP32_OFF32_LINTFLAGS",       CONFSTR,        _CS_XBS5_ILP32_OFF32_LINTFLAGS  },
83   { "XBS5_ILP32_OFFBIG_CFLAGS",         CONFSTR,        _CS_XBS5_ILP32_OFFBIG_CFLAGS    },
84   { "XBS5_ILP32_OFFBIG_LDFLAGS",        CONFSTR,        _CS_XBS5_ILP32_OFFBIG_LDFLAGS   },
85   { "XBS5_ILP32_OFFBIG_LIBS",           CONFSTR,        _CS_XBS5_ILP32_OFFBIG_LIBS      },
86   { "XBS5_ILP32_OFFBIG_LINTFLAGS",      CONFSTR,        _CS_XBS5_ILP32_OFFBIG_LINTFLAGS },
87   { "XBS5_LP64_OFF64_CFLAGS",           CONFSTR,        _CS_XBS5_LP64_OFF64_CFLAGS      },
88   { "XBS5_LP64_OFF64_LDFLAGS",          CONFSTR,        _CS_XBS5_LP64_OFF64_LDFLAGS     },
89   { "XBS5_LP64_OFF64_LIBS",             CONFSTR,        _CS_XBS5_LP64_OFF64_LIBS        },
90   { "XBS5_LP64_OFF64_LINTFLAGS",        CONFSTR,        _CS_XBS5_LP64_OFF64_LINTFLAGS   },
91   { "XBS5_LPBIG_OFFBIG_CFLAGS",         CONFSTR,        _CS_XBS5_LPBIG_OFFBIG_CFLAGS    },
92   { "XBS5_LPBIG_OFFBIG_LDFLAGS",        CONFSTR,        _CS_XBS5_LPBIG_OFFBIG_LDFLAGS   },
93   { "XBS5_LPBIG_OFFBIG_LIBS",           CONFSTR,        _CS_XBS5_LPBIG_OFFBIG_LIBS      },
94   { "XBS5_LPBIG_OFFBIG_LINTFLAGS",      CONFSTR,        _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS },
95   { "XBS5_WIDTH_RESTRICTED_ENVS",       CONFSTR,        _CS_XBS5_WIDTH_RESTRICTED_ENVS  },
96   { "V7_ENV",                           CONFSTR,        _CS_V7_ENV      },
97   { "V6_ENV",                           CONFSTR,        _CS_V6_ENV      },
98
99   /* Symbolic constants from <limits.h> */
100   { "_POSIX_AIO_LISTIO_MAX",            CONSTANT,       _POSIX_AIO_LISTIO_MAX   },
101   { "_POSIX_AIO_MAX",                   CONSTANT,       _POSIX_AIO_MAX          },
102   { "_POSIX_ARG_MAX",                   CONSTANT,       _POSIX_ARG_MAX          },
103   { "_POSIX_CHILD_MAX",                 CONSTANT,       _POSIX_CHILD_MAX        },
104   { "_POSIX_CLOCKRES_MIN",              CONSTANT,       _POSIX_CLOCKRES_MIN     },
105   { "_POSIX_DELAYTIMER_MAX",            CONSTANT,       _POSIX_DELAYTIMER_MAX   },
106   { "_POSIX_HOST_NAME_MAX",             CONSTANT,       _POSIX_HOST_NAME_MAX    },
107   { "_POSIX_LINK_MAX",                  CONSTANT,       _POSIX_LINK_MAX         },
108   { "_POSIX_LOGIN_NAME_MAX",            CONSTANT,       _POSIX_LOGIN_NAME_MAX   },
109   { "_POSIX_MAX_CANON",                 CONSTANT,       _POSIX_MAX_CANON        },
110   { "_POSIX_MAX_INPUT",                 CONSTANT,       _POSIX_MAX_INPUT        },
111   { "_POSIX_MQ_OPEN_MAX",               CONSTANT,       _POSIX_MQ_OPEN_MAX      },
112   { "_POSIX_MQ_PRIO_MAX",               CONSTANT,       _POSIX_MQ_PRIO_MAX      },
113   { "_POSIX_NAME_MAX",                  CONSTANT,       _POSIX_NAME_MAX         },
114   { "_POSIX_NGROUPS_MAX",               CONSTANT,       _POSIX_NGROUPS_MAX      },
115   { "_POSIX_OPEN_MAX",                  CONSTANT,       _POSIX_OPEN_MAX         },
116   { "_POSIX_PATH_MAX",                  CONSTANT,       _POSIX_PATH_MAX         },
117   { "_POSIX_PIPE_BUF",                  CONSTANT,       _POSIX_PIPE_BUF         },
118   { "_POSIX_RE_DUP_MAX",                CONSTANT,       _POSIX_RE_DUP_MAX       },
119   { "_POSIX_RTSIG_MAX",                 CONSTANT,       _POSIX_RTSIG_MAX        },
120   { "_POSIX_SEM_NSEMS_MAX",             CONSTANT,       _POSIX_SEM_NSEMS_MAX    },
121   { "_POSIX_SEM_VALUE_MAX",             CONSTANT,       _POSIX_SEM_VALUE_MAX    },
122   { "_POSIX_SIGQUEUE_MAX",              CONSTANT,       _POSIX_SIGQUEUE_MAX     },
123   { "_POSIX_SSIZE_MAX",                 CONSTANT,       _POSIX_SSIZE_MAX        },
124   { "_POSIX_SS_REPL_MAX",               CONSTANT,       _POSIX_SS_REPL_MAX      },
125   { "_POSIX_STREAM_MAX",                CONSTANT,       _POSIX_STREAM_MAX       },
126   { "_POSIX_SYMLINK_MAX",               CONSTANT,       _POSIX_SYMLINK_MAX      },
127   { "_POSIX_SYMLOOP_MAX",               CONSTANT,       _POSIX_SYMLOOP_MAX      },
128   { "_POSIX_THREAD_DESTRUCTOR_ITERATIONS", CONSTANT,    _POSIX_THREAD_DESTRUCTOR_ITERATIONS     },
129   { "_POSIX_THREAD_KEYS_MAX",           CONSTANT,       _POSIX_THREAD_KEYS_MAX  },
130   { "_POSIX_THREAD_THREADS_MAX",        CONSTANT,       _POSIX_THREAD_THREADS_MAX       },
131   { "_POSIX_TIMER_MAX",                 CONSTANT,       _POSIX_TIMER_MAX        },
132   { "_POSIX_TRACE_EVENT_NAME_MAX",      CONSTANT,       _POSIX_TRACE_EVENT_NAME_MAX     },
133   { "_POSIX_TRACE_NAME_MAX",            CONSTANT,       _POSIX_TRACE_NAME_MAX   },
134   { "_POSIX_TRACE_SYS_MAX",             CONSTANT,       _POSIX_TRACE_SYS_MAX    },
135   { "_POSIX_TRACE_USER_EVENT_MAX",      CONSTANT,       _POSIX_TRACE_USER_EVENT_MAX     },
136   { "_POSIX_TTY_NAME_MAX",              CONSTANT,       _POSIX_TTY_NAME_MAX     },
137   { "_POSIX_TZNAME_MAX",                CONSTANT,       _POSIX_TZNAME_MAX       },
138   { "_POSIX2_BC_BASE_MAX",              CONSTANT,       _POSIX2_BC_BASE_MAX     },
139   { "_POSIX2_BC_DIM_MAX",               CONSTANT,       _POSIX2_BC_DIM_MAX      },
140   { "_POSIX2_BC_SCALE_MAX",             CONSTANT,       _POSIX2_BC_SCALE_MAX    },
141   { "_POSIX2_BC_STRING_MAX",            CONSTANT,       _POSIX2_BC_STRING_MAX   },
142   { "_POSIX2_COLL_WEIGHTS_MAX",         CONSTANT,       _POSIX2_COLL_WEIGHTS_MAX        },
143   { "_POSIX2_EXPR_NEXT_MAX",            CONSTANT,       _POSIX2_EXPR_NEST_MAX   },
144   { "_POSIX2_LINE_MAX",                 CONSTANT,       _POSIX2_LINE_MAX        },
145   { "_POSIX2_RE_DUP_MAX",               CONSTANT,       _POSIX2_RE_DUP_MAX      },
146   { "_XOPEN_IOV_MAX",                   CONSTANT,       _XOPEN_IOV_MAX          },
147   { "_XOPEN_NAME_MAX",                  CONSTANT,       _XOPEN_NAME_MAX         },
148   { "_XOPEN_PATH_MAX",                  CONSTANT,       _XOPEN_PATH_MAX         },
149   { "CHAR_BIT",                         CONSTANT,       CHAR_BIT        },
150   { "CHAR_MAX",                         CONSTANT,       CHAR_MAX        },
151   { "CHAR_MIN",                         CONSTANT,       CHAR_MIN        },
152   { "INT_MAX",                          CONSTANT,       INT_MAX         },
153   { "INT_MIN",                          CONSTANT,       INT_MIN         },
154   { "LLONG_MIN",                        CONSTANT,       LLONG_MIN       },
155   { "LLONG_MAX",                        CONSTANT,       LLONG_MAX       },
156   { "LONG_BIT",                         CONSTANT,       LONG_BIT        },
157   { "LONG_MAX",                         CONSTANT,       LONG_MAX        },
158   { "LONG_MIN",                         CONSTANT,       LONG_MIN        },
159   { "MB_LEN_MAX",                       CONSTANT,       MB_LEN_MAX      },
160   { "SCHAR_MAX",                        CONSTANT,       SCHAR_MAX       },
161   { "SCHAR_MIN",                        CONSTANT,       SCHAR_MIN       },
162   { "SHRT_MAX",                         CONSTANT,       SHRT_MAX        },
163   { "SHRT_MIN",                         CONSTANT,       SHRT_MIN        },
164   { "SSIZE_MAX",                        CONSTANT,       SSIZE_MAX       },
165   { "UCHAR_MAX",                        CONSTANT,       UCHAR_MAX       },
166   { "UINT_MAX",                         CONSTANT,       UINT_MAX        },
167   { "ULLONG_MAX",                       CONSTANT,       ULLONG_MAX      },
168   { "ULONG_MAX",                        CONSTANT,       ULONG_MAX       },
169   { "USHRT_MAX",                        CONSTANT,       USHRT_MAX       },
170   { "WORD_BIT",                         CONSTANT,       WORD_BIT        },
171   { "NL_ARGMAX",                        CONSTANT,       NL_ARGMAX       },
172   { "ML_LANGMAX",                       CONSTANT,       NL_LANGMAX      },
173   { "NL_MSGMAX",                        CONSTANT,       NL_MSGMAX       },
174   { "NL_SETMAX",                        CONSTANT,       NL_SETMAX       },
175   { "NL_TEXTMAX",                       CONSTANT,       NL_TEXTMAX      },
176   { "NZERO",                            CONSTANT,       NZERO           },
177   /* required by POSIX.1-2008 for compatibility with earlier versions */
178   { "POSIX2_BC_BASE_MAX",               CONSTANT,       _POSIX2_BC_BASE_MAX     },
179   { "POSIX2_BC_DIM_MAX",                CONSTANT,       _POSIX2_BC_DIM_MAX      },
180   { "POSIX2_BC_SCALE_MAX",              CONSTANT,       _POSIX2_BC_SCALE_MAX    },
181   { "POSIX2_BC_STRING_MAX",             CONSTANT,       _POSIX2_BC_STRING_MAX   },
182   { "POSIX2_COLL_WEIGHTS_MAX",          CONSTANT,       _POSIX2_COLL_WEIGHTS_MAX        },
183   { "POSIX2_EXPR_NEXT_MAX",             CONSTANT,       _POSIX2_EXPR_NEST_MAX   },
184   { "POSIX2_LINE_MAX",                  CONSTANT,       _POSIX2_LINE_MAX        },
185   { "POSIX2_RE_DUP_MAX",                CONSTANT,       _POSIX2_RE_DUP_MAX      },
186
187   /* Variables from fpathconf() */
188   { "FILESIZEBITS",                     PATHCONF,       _PC_FILESIZEBITS        },
189   { "LINK_MAX",                         PATHCONF,       _PC_LINK_MAX            },
190   { "MAX_CANON",                        PATHCONF,       _PC_MAX_CANON           },
191   { "MAX_INPUT",                        PATHCONF,       _PC_MAX_INPUT           },
192   { "NAME_MAX",                         PATHCONF,       _PC_NAME_MAX            },
193   { "PATH_MAX",                         PATHCONF,       _PC_PATH_MAX            },
194   { "PIPE_BUF",                         PATHCONF,       _PC_PIPE_BUF            },
195   { "POSIX2_SYMLINKS",                  PATHCONF,       _PC_2_SYMLINKS          },
196   { "POSIX_ALLOC_SIZE_MIN",             PATHCONF,       _PC_ALLOC_SIZE_MIN      },
197   { "POSIX_REC_INCR_XFER_SIZE",         PATHCONF,       _PC_REC_INCR_XFER_SIZE  },
198   { "POSIX_REC_MAX_XFER_SIZE",          PATHCONF,       _PC_REC_MAX_XFER_SIZE   },
199   { "POSIX_REC_MIN_XFER_SIZE",          PATHCONF,       _PC_REC_MIN_XFER_SIZE   },
200   { "POSIX_REC_XFER_ALIGN",             PATHCONF,       _PC_REC_XFER_ALIGN      },
201   { "SYMLINK_MAX",                      PATHCONF,       _PC_SYMLINK_MAX         },
202   { "_POSIX_CHOWN_RESTRICTED",          PATHCONF,       _PC_CHOWN_RESTRICTED    },
203   { "_POSIX_NO_TRUNC",                  PATHCONF,       _PC_NO_TRUNC            },
204   { "_POSIX_VDISABLE",                  PATHCONF,       _PC_VDISABLE            },
205   { "_POSIX_ASYNC_IO",                  PATHCONF,       _PC_ASYNC_IO            },
206   { "_POSIX_PRIO_IO",                   PATHCONF,       _PC_PRIO_IO             },
207   { "_POSIX_SYNC_IO",                   PATHCONF,       _PC_SYNC_IO             },
208   { "_POSIX_TIMESTAMP_RESOLUTION",      PATHCONF,       _PC_TIMESTAMP_RESOLUTION        },
209
210   /* Variables from sysconf() */
211   { "AIO_LISTIO_MAX",                   SYSCONF,        _SC_AIO_LISTIO_MAX      },
212   { "AIO_MAX",                          SYSCONF,        _SC_AIO_MAX             },
213   { "AIO_PRIO_DELTA_MAX",               SYSCONF,        _SC_AIO_PRIO_DELTA_MAX  },
214   { "ARG_MAX",                          SYSCONF,        _SC_ARG_MAX             },
215   { "ATEXIT_MAX",                       SYSCONF,        _SC_ATEXIT_MAX          },
216   { "BC_BASE_MAX",                      SYSCONF,        _SC_BC_BASE_MAX         },
217   { "BC_DIM_MAX",                       SYSCONF,        _SC_BC_DIM_MAX          },
218   { "BC_SCALE_MAX",                     SYSCONF,        _SC_BC_SCALE_MAX        },
219   { "BC_STRING_MAX",                    SYSCONF,        _SC_BC_STRING_MAX       },
220   { "CHILD_MAX",                        SYSCONF,        _SC_CHILD_MAX           },
221   { "CLK_TCK",                          SYSCONF,        _SC_CLK_TCK             },
222   { "COLL_WEIGHTS_MAX",                 SYSCONF,        _SC_COLL_WEIGHTS_MAX    },
223   { "DELAYTIMER_MAX",                   SYSCONF,        _SC_DELAYTIMER_MAX      },
224   { "EXPR_NEST_MAX",                    SYSCONF,        _SC_EXPR_NEST_MAX       },
225   { "GETGR_R_SIZE_MAX",                 SYSCONF,        _SC_GETGR_R_SIZE_MAX    },
226   { "GETPW_R_SIZE_MAX",                 SYSCONF,        _SC_GETPW_R_SIZE_MAX    },
227   { "HOST_NAME_MAX",                    SYSCONF,        _SC_HOST_NAME_MAX       },
228   { "IOV_MAX",                          SYSCONF,        _SC_IOV_MAX             },
229   { "LINE_MAX",                         SYSCONF,        _SC_LINE_MAX            },
230   { "LOGIN_NAME_MAX",                   SYSCONF,        _SC_LOGIN_NAME_MAX      },
231   { "MQ_OPEN_MAX",                      SYSCONF,        _SC_MQ_OPEN_MAX         },
232   { "MQ_PRIO_MAX",                      SYSCONF,        _SC_MQ_PRIO_MAX         },
233   { "NGROUPS_MAX",                      SYSCONF,        _SC_NGROUPS_MAX         },
234   { "OPEN_MAX",                         SYSCONF,        _SC_OPEN_MAX            },
235   { "PAGE_SIZE",                        SYSCONF,        _SC_PAGESIZE            },
236   { "PAGESIZE",                         SYSCONF,        _SC_PAGESIZE            },
237   { "PTHREAD_DESTRUCTOR_ITERATIONS",    SYSCONF,        _SC_THREAD_DESTRUCTOR_ITERATIONS        },
238   { "PTHREAD_KEYS_MAX",                 SYSCONF,        _SC_THREAD_KEYS_MAX     },
239   { "PTHREAD_STACK_MIN",                SYSCONF,        _SC_THREAD_STACK_MIN    },
240   { "PTHREAD_THREADS_MAX",              SYSCONF,        _SC_THREAD_THREADS_MAX  },
241   { "RE_DUP_MAX",                       SYSCONF,        _SC_RE_DUP_MAX          },
242   { "RTSIG_MAX",                        SYSCONF,        _SC_RTSIG_MAX           },
243   { "SEM_NSEMS_MAX",                    SYSCONF,        _SC_SEM_NSEMS_MAX       },
244   { "SEM_VALUE_MAX",                    SYSCONF,        _SC_SEM_VALUE_MAX       },
245   { "SIGQUEUE_MAX",                     SYSCONF,        _SC_SIGQUEUE_MAX        },
246   { "STREAM_MAX",                       SYSCONF,        _SC_STREAM_MAX          },
247   { "SYMLOOP_MAX",                      SYSCONF,        _SC_SYMLOOP_MAX         },
248   { "TIMER_MAX",                        SYSCONF,        _SC_TIMER_MAX           },
249   { "TTY_NAME_MAX",                     SYSCONF,        _SC_TTY_NAME_MAX        },
250   { "TZNAME_MAX",                       SYSCONF,        _SC_TZNAME_MAX          },
251   { "_POSIX_ADVISORY_INFO",             SYSCONF,        _SC_ADVISORY_INFO       },
252   { "_POSIX_ASYNCHRONOUS_IO",           SYSCONF,        _SC_ASYNCHRONOUS_IO     },
253   { "_POSIX_BARRIERS",                  SYSCONF,        _SC_BARRIERS            },
254   { "_POSIX_CLOCK_SELECTION",           SYSCONF,        _SC_CLOCK_SELECTION     },
255   { "_POSIX_CPUTIME",                   SYSCONF,        _SC_CPUTIME             },
256   { "_POSIX_FSYNC",                     SYSCONF,        _SC_FSYNC               },
257   { "_POSIX_IPV6",                      SYSCONF,        _SC_IPV6                },
258   { "_POSIX_JOB_CONTROL",               SYSCONF,        _SC_JOB_CONTROL         },
259   { "_POSIX_MAPPED_FILES",              SYSCONF,        _SC_MAPPED_FILES        },
260   { "_POSIX_MEMLOCK",                   SYSCONF,        _SC_MEMLOCK             },
261   { "_POSIX_MEMLOCK_RANGE",             SYSCONF,        _SC_MEMLOCK_RANGE       },
262   { "_POSIX_MEMORY_PROTECTION",         SYSCONF,        _SC_MEMORY_PROTECTION   },
263   { "_POSIX_MESSAGE_PASSING",           SYSCONF,        _SC_MESSAGE_PASSING     },
264   { "_POSIX_MONOTONIC_CLOCK",           SYSCONF,        _SC_MONOTONIC_CLOCK     },
265   { "_POSIX_PRIORITIZED_IO",            SYSCONF,        _SC_PRIORITIZED_IO      },
266   { "_POSIX_PRIORITY_SCHEDULING",       SYSCONF,        _SC_PRIORITY_SCHEDULING         },
267   { "_POSIX_RAW_SOCKETS",               SYSCONF,        _SC_RAW_SOCKETS         },
268   { "_POSIX_READER_WRITER_LOCKS",       SYSCONF,        _SC_READER_WRITER_LOCKS },
269   { "_POSIX_REALTIME_SIGNALS",          SYSCONF,        _SC_REALTIME_SIGNALS    },
270   { "_POSIX_REGEXP",                    SYSCONF,        _SC_REGEXP              },
271   { "_POSIX_SAVED_IDS",                 SYSCONF,        _SC_SAVED_IDS           },
272   { "_POSIX_SEMAPHORES",                SYSCONF,        _SC_SEMAPHORES          },
273   { "_POSIX_SHARED_MEMORY_OBJECTS",     SYSCONF,        _SC_SHARED_MEMORY_OBJECTS       },
274   { "_POSIX_SHELL",                     SYSCONF,        _SC_SHELL               },
275   { "_POSIX_SPAWN",                     SYSCONF,        _SC_SPAWN               },
276   { "_POSIX_SPIN_LOCKS",                SYSCONF,        _SC_SPIN_LOCKS          },
277   { "_POSIX_SPORADIC_SERVER",           SYSCONF,        _SC_SPORADIC_SERVER     },
278   { "_POSIX_SS_REPL_MAX",               SYSCONF,        _SC_SS_REPL_MAX         },
279   { "_POSIX_SYNCHRONIZED_IO",           SYSCONF,        _SC_SYNCHRONIZED_IO     },
280   { "_POSIX_THREAD_ATTR_STACKADDR",     SYSCONF,        _SC_THREAD_ATTR_STACKADDR       },
281   { "_POSIX_THREAD_ATTR_STACKSIZE",     SYSCONF,        _SC_THREAD_ATTR_STACKSIZE       },
282   { "_POSIX_THREAD_CPUTIME",            SYSCONF,        _SC_THREAD_CPUTIME      },
283   { "_POSIX_THREAD_PRIO_INHERIT",       SYSCONF,        _SC_THREAD_PRIO_INHERIT         },
284   { "_POSIX_THREAD_PRIO_PROTECT",       SYSCONF,        _SC_THREAD_PRIO_PROTECT         },
285   { "_POSIX_THREAD_PRIORITY_SCHEDULING",SYSCONF,        _SC_THREAD_PRIORITY_SCHEDULING  },
286   { "_POSIX_THREAD_PROCESS_SHARED",     SYSCONF,        _SC_THREAD_PROCESS_SHARED       },
287   { "_POSIX_THREAD_ROBUST_PRIO_INHERIT",SYSCONF,        _SC_THREAD_ROBUST_PRIO_INHERIT  },
288   { "_POSIX_THREAD_ROBUST_PRIO_PROTECT",SYSCONF,        _SC_THREAD_ROBUST_PRIO_PROTECT  },
289   { "_POSIX_THREAD_SAFE_FUNCTIONS",     SYSCONF,        _SC_THREAD_SAFE_FUNCTIONS       },
290   { "_POSIX_THREAD_SPORADIC_SERVER",    SYSCONF,        _SC_THREAD_SPORADIC_SERVER      },
291   { "_POSIX_THREADS",                   SYSCONF,        _SC_THREADS             },
292   { "_POSIX_TIMEOUTS",                  SYSCONF,        _SC_TIMEOUTS            },
293   { "_POSIX_TIMERS",                    SYSCONF,        _SC_TIMERS              },
294   { "_POSIX_TRACE",                     SYSCONF,        _SC_TRACE               },
295   { "_POSIX_TRACE_EVENT_FILTER",        SYSCONF,        _SC_TRACE_EVENT_FILTER  },
296   { "_POSIX_TRACE_EVENT_NAME_MAX",      SYSCONF,        _SC_TRACE_EVENT_NAME_MAX        },
297   { "_POSIX_TRACE_INHERIT",             SYSCONF,        _SC_TRACE_INHERIT       },
298   { "_POSIX_TRACE_LOG",                 SYSCONF,        _SC_TRACE_LOG           },
299   { "_POSIX_TRACE_NAME_MAX",            SYSCONF,        _SC_TRACE_NAME_MAX              },
300   { "_POSIX_TRACE_SYS_MAX",             SYSCONF,        _SC_TRACE_SYS_MAX               },
301   { "_POSIX_TRACE_USER_EVENT_MAX",      SYSCONF,        _SC_TRACE_USER_EVENT_MAX                },
302   { "_POSIX_TYPED_MEMORY_OBJECTS",      SYSCONF,        _SC_TYPED_MEMORY_OBJECTS        },
303   { "_POSIX_VERSION",                   SYSCONF,        _SC_VERSION             },
304   { "_POSIX_V7_ILP32_OFF32",            SYSCONF,        _SC_V7_ILP32_OFF32      },
305   { "_POSIX_V7_ILP32_OFFBIG",           SYSCONF,        _SC_V7_ILP32_OFFBIG     },
306   { "_POSIX_V7_LP64_OFF64",             SYSCONF,        _SC_V7_LP64_OFF64       },
307   { "_POSIX_V7_LPBIG_OFFBIG",           SYSCONF,        _SC_V7_LPBIG_OFFBIG     },
308   { "_POSIX_V6_ILP32_OFF32",            SYSCONF,        _SC_V6_ILP32_OFF32      },
309   { "_POSIX_V6_ILP32_OFFBIG",           SYSCONF,        _SC_V6_ILP32_OFFBIG     },
310   { "_POSIX_V6_LP64_OFF64",             SYSCONF,        _SC_V6_LP64_OFF64       },
311   { "_POSIX_V6_LPBIG_OFFBIG",           SYSCONF,        _SC_V6_LPBIG_OFFBIG     },
312   { "_POSIX2_C_BIND",                   SYSCONF,        _SC_2_C_BIND            },
313   { "_POSIX2_C_DEV",                    SYSCONF,        _SC_2_C_DEV             },
314   { "_POSIX2_CHAR_TERM",                SYSCONF,        _SC_2_CHAR_TERM         },
315   { "_POSIX2_FORT_DEV",                 SYSCONF,        _SC_2_FORT_DEV          },
316   { "_POSIX2_FORT_RUN",                 SYSCONF,        _SC_2_FORT_RUN          },
317   { "_POSIX2_LOCALEDEF",                SYSCONF,        _SC_2_LOCALEDEF         },
318   { "_POSIX2_PBS",                      SYSCONF,        _SC_2_PBS               },
319   { "_POSIX2_PBS_ACCOUNTING",           SYSCONF,        _SC_2_PBS_ACCOUNTING    },
320   { "_POSIX2_PBS_CHECKPOINT",           SYSCONF,        _SC_2_PBS_CHECKPOINT    },
321   { "_POSIX2_PBS_LOCATE",               SYSCONF,        _SC_2_PBS_LOCATE        },
322   { "_POSIX2_PBS_MESSAGE",              SYSCONF,        _SC_2_PBS_MESSAGE       },
323   { "_POSIX2_PBS_TRACK",                SYSCONF,        _SC_2_PBS_TRACK         },
324   { "_POSIX2_SW_DEV",                   SYSCONF,        _SC_2_SW_DEV            },
325   { "_POSIX2_UPE",                      SYSCONF,        _SC_2_UPE               },
326   { "_POSIX2_VERSION",                  SYSCONF,        _SC_2_VERSION           },
327   { "_XBS5_ILP32_OFF32",                SYSCONF,        _SC_XBS5_ILP32_OFF32    },
328   { "_XBS5_ILP32_OFFBIG",               SYSCONF,        _SC_XBS5_ILP32_OFFBIG   },
329   { "_XBS5_LP64_OFF64",                 SYSCONF,        _SC_XBS5_LP64_OFF64     },
330   { "_XBS5_LPBIG_OFFBIG",               SYSCONF,        _SC_XBS5_LPBIG_OFFBIG   },
331   { "_XOPEN_CRYPT",                     SYSCONF,        _SC_XOPEN_CRYPT         },
332   { "_XOPEN_ENH_I18N",                  SYSCONF,        _SC_XOPEN_ENH_I18N      },
333   { "_XOPEN_LEGACY",                    SYSCONF,        _SC_XOPEN_LEGACY        },
334   { "_XOPEN_REALTIME",                  SYSCONF,        _SC_XOPEN_REALTIME      },
335   { "_XOPEN_REALTIME_THREADS",          SYSCONF,        _SC_XOPEN_REALTIME_THREADS      },
336   { "_XOPEN_SHM",                       SYSCONF,        _SC_XOPEN_SHM           },
337   { "_XOPEN_STREAMS",                   SYSCONF,        _SC_XOPEN_STREAMS       },
338   { "_XOPEN_UNIX",                      SYSCONF,        _SC_XOPEN_UNIX          },
339   { "_XOPEN_UUCP",                      SYSCONF,        _SC_XOPEN_UUCP          },
340   { "_XOPEN_VERSION",                   SYSCONF,        _SC_XOPEN_VERSION       },
341   /* for compatibility with earlier versions */
342   { "POSIX2_C_BIND",                    SYSCONF,        _SC_2_C_BIND            },
343   { "POSIX2_C_DEV",                     SYSCONF,        _SC_2_C_DEV             },
344   { "POSIX2_CHAR_TERM",                 SYSCONF,        _SC_2_CHAR_TERM         },
345   { "POSIX2_FORT_DEV",                  SYSCONF,        _SC_2_FORT_DEV          },
346   { "POSIX2_FORT_RUN",                  SYSCONF,        _SC_2_FORT_RUN          },
347   { "POSIX2_LOCALEDEF",                 SYSCONF,        _SC_2_LOCALEDEF         },
348   { "POSIX2_PBS",                       SYSCONF,        _SC_2_PBS               },
349   { "POSIX2_PBS_ACCOUNTING",            SYSCONF,        _SC_2_PBS_ACCOUNTING    },
350   { "POSIX2_PBS_CHECKPOINT",            SYSCONF,        _SC_2_PBS_CHECKPOINT    },
351   { "POSIX2_PBS_LOCATE",                SYSCONF,        _SC_2_PBS_LOCATE        },
352   { "POSIX2_PBS_MESSAGE",               SYSCONF,        _SC_2_PBS_MESSAGE       },
353   { "POSIX2_PBS_TRACK",                 SYSCONF,        _SC_2_PBS_TRACK         },
354   { "POSIX2_SW_DEV",                    SYSCONF,        _SC_2_SW_DEV            },
355   { "POSIX2_UPE",                       SYSCONF,        _SC_2_UPE               },
356   { "POSIX2_VERSION",                   SYSCONF,        _SC_2_VERSION           },
357   /* implementation-specific values */
358   { "_NPROCESSORS_CONF",                SYSCONF,        _SC_NPROCESSORS_CONF    },
359   { "_NPROCESSORS_ONLN",                SYSCONF,        _SC_NPROCESSORS_ONLN    },
360   { "_AVPHYS_PAGES",                    SYSCONF,        _SC_AVPHYS_PAGES        },
361   { "_PHYS_PAGES",                      SYSCONF,        _SC_PHYS_PAGES          },
362
363   { NULL,                               CONSTANT,        0L }
364 };
365
366 struct spec_variable {
367   const char *name;
368   int valid;
369 };
370
371 static const struct spec_variable spec_table[] = {
372   { "POSIX_V7_ILP32_OFF32",     0 },
373   { "POSIX_V7_ILP32_OFFBIG",    1 },
374   { "POSIX_V7_LP64_OFF64",      0 },
375   { "POSIX_V7_LPBIG_OFFBIG",    0 },
376   { "POSIX_V6_ILP32_OFF32",     0 },
377   { "POSIX_V6_ILP32_OFFBIG",    1 },
378   { "POSIX_V6_LP64_OFF64",      0 },
379   { "POSIX_V6_LPBIG_OFFBIG",    0 },
380   { "XBS5_ILP32_OFF32",         0 },
381   { "XBS5_ILP32_OFFBIG",        1 },
382   { "XBS5_LP64_OFF64",          0 },
383   { "XBS5_LPBIG_OFFBIG",        0 },
384   { NULL, 0 },
385 };
386
387 static int a_flag = 0;          /* list all variables */
388 static int v_flag = 0;          /* follow given specification */
389
390 static void
391 print_longvar (const char *name, long long value)
392 {
393   if (a_flag)
394     printf ("%-35s %lld\n", name, value);
395   else
396     printf ("%lld\n", value);
397 }
398
399 static void
400 print_strvar (const char *name, const char *sval)
401 {
402   if (a_flag)
403     printf ("%-35s %s\n", name, sval);
404   else
405     printf ("%s\n", sval);
406 }
407
408 static void
409 printvar (const struct conf_variable *cp, const char *pathname)
410 {
411   size_t slen;
412   char *sval;
413   long val;
414
415   switch (cp->type)
416     {
417     case CONSTANT:
418       print_longvar (cp->name, cp->value);
419       break;
420
421     case CONFSTR:
422       errno = 0;
423       slen = confstr ((int) cp->value, NULL, 0);
424       if (slen == 0)
425         {
426           if (errno == 0)
427             print_strvar (cp->name, "undefined");
428           return;
429         }
430
431       if ((sval = malloc (slen)) == NULL)
432         error (EXIT_FAILURE, 0, "Can't allocate %zu bytes", slen);
433
434       errno = 0;
435       if (confstr ((int) cp->value, sval, slen) == 0)
436         print_strvar (cp->name, "undefined");
437       else
438         print_strvar (cp->name, sval);
439
440       free (sval);
441       break;
442
443     case SYSCONF:
444       errno = 0;
445       if ((val = sysconf ((int) cp->value)) == -1)
446         {
447           if (a_flag && errno != 0)
448             return; /* Just skip invalid variables */
449           print_strvar (cp->name, "undefined");
450         }
451       else
452         print_longvar (cp->name, val);
453       break;
454
455     case PATHCONF:
456       errno = 0;
457       if ((val = pathconf (pathname, (int) cp->value)) == -1)
458         {
459           if (a_flag && errno != 0)
460             return; /* Just skip invalid variables */
461           print_strvar (cp->name, "undefined");
462         }
463       else
464         print_longvar (cp->name, val);
465       break;
466     }
467 }
468
469 static void
470 usage (void)
471 {
472   fprintf (stderr,
473            "Usage: %s [-v specification] variable_name [pathname]\n"
474            "       %s -a [pathname]\n",
475            program_invocation_short_name, program_invocation_short_name);
476   exit (EXIT_FAILURE);
477 }
478
479 int
480 main (int argc, char **argv)
481 {
482   int ch;
483   const struct conf_variable *cp;
484   const struct spec_variable *sp;
485   const char *varname, *pathname;
486   int found;
487
488   setlocale (LC_ALL, "");
489
490   while ((ch = getopt (argc, argv, "av")) != -1)
491     {
492       switch (ch)
493         {
494         case 'a':
495           a_flag = 1;
496           break;
497         case 'v':
498           v_flag = 1;
499           break;
500         case '?':
501         default:
502           usage ();
503         }
504     }
505   argc -= optind;
506   argv += optind;
507
508   if (v_flag)
509     {
510       if (a_flag || argc < 2)
511         usage ();
512       for (sp = spec_table; sp->name != NULL; sp++)
513         {
514           if (strcmp (argv[0], sp->name) == 0)
515             {
516               if (sp->valid != 1)
517                 error (EXIT_FAILURE, 0, "unsupported specification \"%s\"", argv[0]);
518               break;
519             }
520         }
521       if (sp->name == NULL)
522         error (EXIT_FAILURE, 0, "unknown specification \"%s\"", argv[0]);
523       argc--;
524       argv++;
525     }
526
527   if (!a_flag)
528     {
529       if (argc == 0)
530         usage ();
531       varname = argv[0];
532       argc--;
533       argv++;
534     }
535   else
536     varname = NULL;
537
538   if (argc > 1)
539     usage ();
540   pathname = argv[0];  /* may be NULL */
541
542   found = 0;
543   for (cp = conf_table; cp->name != NULL; cp++)
544     {
545       if (a_flag || strcmp (varname, cp->name) == 0)
546         {
547           /* LINTED weird expression */
548           if ((cp->type == PATHCONF) == (pathname != NULL))
549             {
550               printvar (cp, pathname);
551               found = 1;
552             }
553           else if (!a_flag)
554             usage ();
555         }
556     }
557
558   if (!a_flag && !found)
559     error (EXIT_FAILURE, 0, "Unrecognized variable `%s'", varname);
560
561   fflush (stdout);
562   return ferror (stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
563 }
564