Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / examples / loadables / getconf.c
1 /*
2  * Copyright (c) 1994 Winning Strategies, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Winning Strategies, Inc.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /*
32  * POSIX.2 getconf utility
33  *
34  * Written by:
35  *      J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
36  */
37
38 #ifndef lint
39 static char rcsid[] = "$Id: getconf.c,v 1.2 1994/05/10 00:04:12 jtc Exp $";
40 #endif /* not lint */
41
42 #include <stdio.h>
43 #include <limits.h>
44 #include <locale.h>
45 #include <unistd.h>
46 #include <errno.h>
47 #include "bashansi.h"
48 #include "shell.h"
49 #include "builtins.h"
50 #include "stdc.h"
51
52
53 struct conf_variable
54 {
55   const char *name;
56   enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT } type;
57   long value;
58 };
59
60 /* BSD/OS does not define this; use Posix.2 recommended minimum value. */
61 #ifndef _POSIX2_COLL_WEIGHTS_MAX
62 #define _POSIX2_COLL_WEIGHTS_MAX 2
63 #endif
64
65 static const struct conf_variable conf_table[] =
66 {
67   { "PATH",                     CONFSTR,        _CS_PATH                },
68
69   /* Utility Limit Minimum Values */
70   { "POSIX2_BC_BASE_MAX",       CONSTANT,       _POSIX2_BC_BASE_MAX     },
71   { "POSIX2_BC_DIM_MAX",        CONSTANT,       _POSIX2_BC_DIM_MAX      },
72   { "POSIX2_BC_SCALE_MAX",      CONSTANT,       _POSIX2_BC_SCALE_MAX    },
73   { "POSIX2_BC_STRING_MAX",     CONSTANT,       _POSIX2_BC_STRING_MAX   },
74   { "POSIX2_COLL_WEIGHTS_MAX",  CONSTANT,       _POSIX2_COLL_WEIGHTS_MAX },
75   { "POSIX2_EXPR_NEST_MAX",     CONSTANT,       _POSIX2_EXPR_NEST_MAX   },
76   { "POSIX2_LINE_MAX",          CONSTANT,       _POSIX2_LINE_MAX        },
77   { "POSIX2_RE_DUP_MAX",        CONSTANT,       _POSIX2_RE_DUP_MAX      },
78   { "POSIX2_VERSION",           CONSTANT,       _POSIX2_VERSION         },
79
80   /* POSIX.1 Minimum Values */
81   { "_POSIX_ARG_MAX",           CONSTANT,       _POSIX_ARG_MAX          },
82   { "_POSIX_CHILD_MAX",         CONSTANT,       _POSIX_CHILD_MAX        },
83   { "_POSIX_LINK_MAX",          CONSTANT,       _POSIX_LINK_MAX         },
84   { "_POSIX_MAX_CANON",         CONSTANT,       _POSIX_MAX_CANON        },
85   { "_POSIX_MAX_INPUT",         CONSTANT,       _POSIX_MAX_INPUT        },
86   { "_POSIX_NAME_MAX",          CONSTANT,       _POSIX_NAME_MAX         },
87   { "_POSIX_NGROUPS_MAX",       CONSTANT,       _POSIX_NGROUPS_MAX      },
88   { "_POSIX_OPEN_MAX",          CONSTANT,       _POSIX_OPEN_MAX         },
89   { "_POSIX_PATH_MAX",          CONSTANT,       _POSIX_PIPE_BUF         },
90   { "_POSIX_PIPE_BUF",          CONSTANT,       _POSIX_PIPE_BUF         },
91   { "_POSIX_SSIZE_MAX",         CONSTANT,       _POSIX_SSIZE_MAX        },
92   { "_POSIX_STREAM_MAX",        CONSTANT,       _POSIX_STREAM_MAX       },
93   { "_POSIX_TZNAME_MAX",        CONSTANT,       _POSIX_TZNAME_MAX       },
94
95   /* Symbolic Utility Limits */
96   { "BC_BASE_MAX",              SYSCONF,        _SC_BC_BASE_MAX         },
97   { "BC_DIM_MAX",               SYSCONF,        _SC_BC_DIM_MAX          },
98   { "BC_SCALE_MAX",             SYSCONF,        _SC_BC_SCALE_MAX        },
99   { "BC_STRING_MAX",            SYSCONF,        _SC_BC_STRING_MAX       },
100   { "COLL_WEIGHTS_MAX",         SYSCONF,        _SC_COLL_WEIGHTS_MAX    },
101   { "EXPR_NEST_MAX",            SYSCONF,        _SC_EXPR_NEST_MAX       },
102   { "LINE_MAX",                 SYSCONF,        _SC_LINE_MAX            },
103   { "RE_DUP_MAX",               SYSCONF,        _SC_RE_DUP_MAX          },
104
105   /* Optional Facility Configuration Values */
106   { "POSIX2_C_BIND",            SYSCONF,        _SC_2_C_BIND            },
107   { "POSIX2_C_DEV",             SYSCONF,        _SC_2_C_DEV             },
108   { "POSIX2_CHAR_TERM",         SYSCONF,        _SC_2_CHAR_TERM         },
109   { "POSIX2_FORT_DEV",          SYSCONF,        _SC_2_FORT_DEV          },
110   { "POSIX2_FORT_RUN",          SYSCONF,        _SC_2_FORT_RUN          },
111   { "POSIX2_LOCALEDEF",         SYSCONF,        _SC_2_LOCALEDEF         },
112   { "POSIX2_SW_DEV",            SYSCONF,        _SC_2_SW_DEV            },
113   { "POSIX2_UPE",               SYSCONF,        _SC_2_UPE               },
114
115   /* POSIX.1 Configurable System Variables */
116   { "ARG_MAX",                  SYSCONF,        _SC_ARG_MAX             },
117   { "CHILD_MAX",                SYSCONF,        _SC_CHILD_MAX           },
118   { "CLK_TCK",                  SYSCONF,        _SC_CLK_TCK             },
119   { "NGROUPS_MAX",              SYSCONF,        _SC_NGROUPS_MAX         },
120   { "OPEN_MAX",                 SYSCONF,        _SC_OPEN_MAX            },
121   { "STREAM_MAX",               SYSCONF,        _SC_STREAM_MAX          },
122   { "TZNAME_MAX",               SYSCONF,        _SC_TZNAME_MAX          },
123   { "_POSIX_JOB_CONTROL",       SYSCONF,        _SC_JOB_CONTROL         },
124   { "_POSIX_SAVED_IDS",         SYSCONF,        _SC_SAVED_IDS           },
125   { "_POSIX_VERSION",           SYSCONF,        _SC_VERSION             },
126
127   { "LINK_MAX",                 PATHCONF,       _PC_LINK_MAX            },
128   { "MAX_CANON",                PATHCONF,       _PC_MAX_CANON           },
129   { "MAX_INPUT",                PATHCONF,       _PC_MAX_INPUT           },
130   { "NAME_MAX",                 PATHCONF,       _PC_NAME_MAX            },
131   { "PATH_MAX",                 PATHCONF,       _PC_PATH_MAX            },
132   { "PIPE_BUF",                 PATHCONF,       _PC_PIPE_BUF            },
133   { "_POSIX_CHOWN_RESTRICTED",  PATHCONF,       _PC_CHOWN_RESTRICTED    },
134   { "_POSIX_NO_TRUNC",          PATHCONF,       _PC_NO_TRUNC            },
135   { "_POSIX_VDISABLE",          PATHCONF,       _PC_VDISABLE            },
136
137   { NULL }
138 };
139
140 extern char *this_command_name;
141 extern char *xmalloc ();
142 extern char **make_builtin_argv ();
143 static int getconf_main ();
144
145 int
146 getconf_builtin (list)
147      WORD_LIST *list;
148 {
149   int c, r;
150   char **v;
151   WORD_LIST *l;
152
153   v = make_builtin_argv (list, &c);
154   r = getconf_main (c, v);
155   free (v);
156
157   return r;
158 }
159
160 static int
161 getconf_main(argc, argv)
162         int argc;
163         char **argv;
164 {
165         int ch;
166         const struct conf_variable *cp;
167
168         long val;
169         size_t slen;
170         char *sval;
171
172         setlocale(LC_ALL, "");
173
174         while ((ch = getopt(argc, argv, "")) != -1) {
175                 switch (ch) {
176                 case '?':
177                 default:
178                         builtin_usage();
179                         return(EX_USAGE);
180                         /* NOTREACHED */
181                 }
182         }
183         argc -= optind;
184         argv += optind;
185
186         if (argc < 1 || argc > 2) {
187                 builtin_usage();
188                 return(EX_USAGE);
189                 /* NOTREACHED */
190         }
191
192         for (cp = conf_table; cp->name != NULL; cp++) {
193                 if (strcmp(*argv, cp->name) == 0)
194                         break;
195         }
196         if (cp->name == NULL) {
197                 builtin_error ("%s: unknown variable", *argv);
198                 return (EXECUTION_FAILURE);
199         }
200
201         if (cp->type == PATHCONF) {
202                 if (argc != 2) {
203                         builtin_usage();
204                         return(EX_USAGE);
205                 }
206         } else {
207                 if (argc != 1) {
208                         builtin_usage();
209                         return(EX_USAGE);
210                 }
211         }
212
213         switch (cp->type) {
214         case CONSTANT:
215                 printf("%ld\n", cp->value);
216                 break;
217
218         case CONFSTR:
219                 slen = confstr (cp->value, (char *) 0, (size_t) 0);
220
221                 sval = xmalloc(slen);
222
223                 confstr(cp->value, sval, slen);
224                 printf("%s\n", sval);
225                 break;
226
227         case SYSCONF:
228                 errno = 0;
229                 if ((val = sysconf(cp->value)) == -1) {
230                         if (errno != 0) {
231                                 builtin_error ("%s", strerror (errno));
232                                 return (EXECUTION_FAILURE);
233                         }
234
235                         printf ("undefined\n");
236                 } else {
237                         printf("%ld\n", val);
238                 }
239                 break;
240
241         case PATHCONF:
242                 errno = 0;
243                 if ((val = pathconf(argv[1], cp->value)) == -1) {
244                         if (errno != 0) {
245                                 builtin_error ("%s: %s", argv[1], strerror (errno));
246                                 return (EXECUTION_FAILURE);
247                         }
248
249                         printf ("undefined\n");
250                 } else {
251                         printf ("%ld\n", val);
252                 }
253                 break;
254         }
255
256         return (ferror(stdout) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
257 }
258
259 static char *getconf_doc[] = {
260         "getconf writes the current value of a configurable system limit or",
261         "option variable to the standard output.",
262         (char *)NULL
263 };
264
265 struct builtin getconf_struct = {
266         "getconf",
267         getconf_builtin,
268         BUILTIN_ENABLED,
269         getconf_doc,
270         "getconf sysvar or getconf pathvar pathname",
271         0
272 };