Implement the NETBSD_SHELL readonly unexportable unimportable variable (with its current value set at 20160401) as discussed on current-users and tech-userlevel. This also includes the necessary support to implement it properly (particularly the unexportable part) and adds options to the export command to support unexportable variables. Also implement the "posix" option (no single letter equivalent) which gets its default value from whether or not POSIXLY_CORRECT is set in the environment when the shell starts (but can be changed just like any other option using -o and +o on the command line, or the set builtin command.) While there, fix all uses of options so it is possible to have options that have a short (one char) name, and no long name, just as it has been possible to have options with a long name and no short name, though there are currently none (with no long name). For now, the only use of the posix option is to control whether ${ENV} is read at startup by a non-interactive shell, so changing it with set is not usful - that might change in the future. (from kre@)diff -r1.100 -r1.101 src/bin/sh/expand.c
(christos)
--- src/bin/sh/expand.c 2016/03/31 13:27:44 1.100
+++ src/bin/sh/expand.c 2016/03/31 16:16:35 1.101
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: expand.c,v 1.100 2016/03/31 13:27:44 christos Exp $ */ | 1 | /* $NetBSD: expand.c,v 1.101 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | #if 0 | 37 | #if 0 | |
38 | static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; | 38 | static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: expand.c,v 1.100 2016/03/31 13:27:44 christos Exp $"); | 40 | __RCSID("$NetBSD: expand.c,v 1.101 2016/03/31 16:16:35 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif /* not lint */ | 42 | #endif /* not lint */ | |
43 | 43 | |||
44 | #include <sys/types.h> | 44 | #include <sys/types.h> | |
45 | #include <sys/time.h> | 45 | #include <sys/time.h> | |
46 | #include <sys/stat.h> | 46 | #include <sys/stat.h> | |
47 | #include <errno.h> | 47 | #include <errno.h> | |
48 | #include <dirent.h> | 48 | #include <dirent.h> | |
49 | #include <unistd.h> | 49 | #include <unistd.h> | |
50 | #include <pwd.h> | 50 | #include <pwd.h> | |
51 | #include <limits.h> | 51 | #include <limits.h> | |
52 | #include <stdlib.h> | 52 | #include <stdlib.h> | |
53 | #include <stdio.h> | 53 | #include <stdio.h> | |
@@ -897,27 +897,27 @@ varvalue(char *name, int quoted, int sub | @@ -897,27 +897,27 @@ varvalue(char *name, int quoted, int sub | |||
897 | goto numvar; | 897 | goto numvar; | |
898 | case '?': | 898 | case '?': | |
899 | num = exitstatus; | 899 | num = exitstatus; | |
900 | goto numvar; | 900 | goto numvar; | |
901 | case '#': | 901 | case '#': | |
902 | num = shellparam.nparam; | 902 | num = shellparam.nparam; | |
903 | goto numvar; | 903 | goto numvar; | |
904 | case '!': | 904 | case '!': | |
905 | num = backgndpid; | 905 | num = backgndpid; | |
906 | numvar: | 906 | numvar: | |
907 | expdest = cvtnum(num, expdest); | 907 | expdest = cvtnum(num, expdest); | |
908 | break; | 908 | break; | |
909 | case '-': | 909 | case '-': | |
910 | for (i = 0; optlist[i].name; i++) { | 910 | for (i = 0; optlist[i].name || optlist[i].letter; i++) { | |
911 | if (optlist[i].val && optlist[i].letter) | 911 | if (optlist[i].val && optlist[i].letter) | |
912 | STPUTC(optlist[i].letter, expdest); | 912 | STPUTC(optlist[i].letter, expdest); | |
913 | } | 913 | } | |
914 | break; | 914 | break; | |
915 | case '@': | 915 | case '@': | |
916 | if (flag & EXP_FULL && quoted) { | 916 | if (flag & EXP_FULL && quoted) { | |
917 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | 917 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | |
918 | STRTODEST(p); | 918 | STRTODEST(p); | |
919 | if (*ap) | 919 | if (*ap) | |
920 | /* A NUL separates args inside "" */ | 920 | /* A NUL separates args inside "" */ | |
921 | STPUTC('\0', expdest); | 921 | STPUTC('\0', expdest); | |
922 | } | 922 | } | |
923 | break; | 923 | break; |
--- src/bin/sh/main.c 2016/03/27 14:34:46 1.63
+++ src/bin/sh/main.c 2016/03/31 16:16:35 1.64
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: main.c,v 1.63 2016/03/27 14:34:46 christos Exp $ */ | 1 | /* $NetBSD: main.c,v 1.64 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -32,27 +32,27 @@ | @@ -32,27 +32,27 @@ | |||
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | __COPYRIGHT("@(#) Copyright (c) 1991, 1993\ | 37 | __COPYRIGHT("@(#) Copyright (c) 1991, 1993\ | |
38 | The Regents of the University of California. All rights reserved."); | 38 | The Regents of the University of California. All rights reserved."); | |
39 | #endif /* not lint */ | 39 | #endif /* not lint */ | |
40 | 40 | |||
41 | #ifndef lint | 41 | #ifndef lint | |
42 | #if 0 | 42 | #if 0 | |
43 | static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; | 43 | static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; | |
44 | #else | 44 | #else | |
45 | __RCSID("$NetBSD: main.c,v 1.63 2016/03/27 14:34:46 christos Exp $"); | 45 | __RCSID("$NetBSD: main.c,v 1.64 2016/03/31 16:16:35 christos Exp $"); | |
46 | #endif | 46 | #endif | |
47 | #endif /* not lint */ | 47 | #endif /* not lint */ | |
48 | 48 | |||
49 | #include <errno.h> | 49 | #include <errno.h> | |
50 | #include <stdio.h> | 50 | #include <stdio.h> | |
51 | #include <signal.h> | 51 | #include <signal.h> | |
52 | #include <sys/stat.h> | 52 | #include <sys/stat.h> | |
53 | #include <unistd.h> | 53 | #include <unistd.h> | |
54 | #include <stdlib.h> | 54 | #include <stdlib.h> | |
55 | #include <locale.h> | 55 | #include <locale.h> | |
56 | #include <fcntl.h> | 56 | #include <fcntl.h> | |
57 | 57 | |||
58 | 58 | |||
@@ -72,27 +72,26 @@ __RCSID("$NetBSD: main.c,v 1.63 2016/03/ | @@ -72,27 +72,26 @@ __RCSID("$NetBSD: main.c,v 1.63 2016/03/ | |||
72 | #include "var.h" | 72 | #include "var.h" | |
73 | #include "show.h" | 73 | #include "show.h" | |
74 | #include "memalloc.h" | 74 | #include "memalloc.h" | |
75 | #include "error.h" | 75 | #include "error.h" | |
76 | #include "init.h" | 76 | #include "init.h" | |
77 | #include "mystring.h" | 77 | #include "mystring.h" | |
78 | #include "exec.h" | 78 | #include "exec.h" | |
79 | #include "cd.h" | 79 | #include "cd.h" | |
80 | 80 | |||
81 | #define PROFILE 0 | 81 | #define PROFILE 0 | |
82 | 82 | |||
83 | int rootpid; | 83 | int rootpid; | |
84 | int rootshell; | 84 | int rootshell; | |
85 | int posix; | |||
86 | #if PROFILE | 85 | #if PROFILE | |
87 | short profile_buf[16384]; | 86 | short profile_buf[16384]; | |
88 | extern int etext(); | 87 | extern int etext(); | |
89 | #endif | 88 | #endif | |
90 | 89 | |||
91 | STATIC void read_profile(const char *); | 90 | STATIC void read_profile(const char *); | |
92 | int main(int, char **); | 91 | int main(int, char **); | |
93 | 92 | |||
94 | /* | 93 | /* | |
95 | * Main routine. We initialize things, parse the arguments, execute | 94 | * Main routine. We initialize things, parse the arguments, execute | |
96 | * profiles if we're a login shell, and then call cmdloop to execute | 95 | * profiles if we're a login shell, and then call cmdloop to execute | |
97 | * commands. The setjmp call sets up the location to jump to when an | 96 | * commands. The setjmp call sets up the location to jump to when an | |
98 | * exception occurs. When an exception occurs the variable "state" | 97 | * exception occurs. When an exception occurs the variable "state" |
--- src/bin/sh/options.c 2016/03/08 14:08:39 1.45
+++ src/bin/sh/options.c 2016/03/31 16:16:35 1.46
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: options.c,v 1.45 2016/03/08 14:08:39 christos Exp $ */ | 1 | /* $NetBSD: options.c,v 1.46 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | #if 0 | 37 | #if 0 | |
38 | static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; | 38 | static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: options.c,v 1.45 2016/03/08 14:08:39 christos Exp $"); | 40 | __RCSID("$NetBSD: options.c,v 1.46 2016/03/31 16:16:35 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif /* not lint */ | 42 | #endif /* not lint */ | |
43 | 43 | |||
44 | #include <signal.h> | 44 | #include <signal.h> | |
45 | #include <unistd.h> | 45 | #include <unistd.h> | |
46 | #include <stdlib.h> | 46 | #include <stdlib.h> | |
47 | 47 | |||
48 | #include "shell.h" | 48 | #include "shell.h" | |
49 | #define DEFINE_OPTIONS | 49 | #define DEFINE_OPTIONS | |
50 | #include "options.h" | 50 | #include "options.h" | |
51 | #undef DEFINE_OPTIONS | 51 | #undef DEFINE_OPTIONS | |
52 | #include "builtins.h" | 52 | #include "builtins.h" | |
53 | #include "nodes.h" /* for other header files */ | 53 | #include "nodes.h" /* for other header files */ | |
@@ -214,45 +214,60 @@ set_opt_val(size_t i, int val) | @@ -214,45 +214,60 @@ set_opt_val(size_t i, int val) | |||
214 | optlist[j].val = 0; | 214 | optlist[j].val = 0; | |
215 | } | 215 | } | |
216 | optlist[i].val = val; | 216 | optlist[i].val = val; | |
217 | #ifdef DEBUG | 217 | #ifdef DEBUG | |
218 | if (&optlist[i].val == &debug) | 218 | if (&optlist[i].val == &debug) | |
219 | opentrace(); | 219 | opentrace(); | |
220 | #endif | 220 | #endif | |
221 | } | 221 | } | |
222 | 222 | |||
223 | STATIC void | 223 | STATIC void | |
224 | minus_o(char *name, int val) | 224 | minus_o(char *name, int val) | |
225 | { | 225 | { | |
226 | size_t i; | 226 | size_t i; | |
227 | const char *sep = ": "; | |||
227 | 228 | |||
228 | if (name == NULL) { | 229 | if (name == NULL) { | |
229 | if (val) { | 230 | if (val) { | |
230 | out1str("Current option settings\n"); | 231 | out1str("Current option settings"); | |
231 | for (i = 0; i < NOPTS; i++) { | 232 | for (i = 0; i < NOPTS; i++) { | |
232 | out1fmt("%-16s%s\n", optlist[i].name, | 233 | if (optlist[i].name == NULL) { | |
234 | out1fmt("%s%c%c", sep, | |||
235 | "+-"[optlist[i].val], | |||
236 | optlist[i].letter); | |||
237 | sep = ", "; | |||
238 | } | |||
239 | } | |||
240 | out1c('\n'); | |||
241 | for (i = 0; i < NOPTS; i++) { | |||
242 | if (optlist[i].name) | |||
243 | out1fmt("%-16s%s\n", optlist[i].name, | |||
233 | optlist[i].val ? "on" : "off"); | 244 | optlist[i].val ? "on" : "off"); | |
234 | } | 245 | } | |
235 | } else { | 246 | } else { | |
236 | out1str("set"); | 247 | out1str("set"); | |
237 | for (i = 0; i < NOPTS; i++) { | 248 | for (i = 0; i < NOPTS; i++) { | |
238 | out1fmt(" %co %s", | 249 | if (optlist[i].name) | |
250 | out1fmt(" %co %s", | |||
239 | "+-"[optlist[i].val], optlist[i].name); | 251 | "+-"[optlist[i].val], optlist[i].name); | |
252 | else | |||
253 | out1fmt(" %c%c", "+-"[optlist[i].val], | |||
254 | optlist[i].letter); | |||
240 | } | 255 | } | |
241 | out1str("\n"); | 256 | out1c('\n'); | |
242 | } | 257 | } | |
243 | } else { | 258 | } else { | |
244 | for (i = 0; i < NOPTS; i++) | 259 | for (i = 0; i < NOPTS; i++) | |
245 | if (equal(name, optlist[i].name)) { | 260 | if (optlist[i].name && equal(name, optlist[i].name)) { | |
246 | set_opt_val(i, val); | 261 | set_opt_val(i, val); | |
247 | return; | 262 | return; | |
248 | } | 263 | } | |
249 | error("Illegal option -o %s", name); | 264 | error("Illegal option -o %s", name); | |
250 | } | 265 | } | |
251 | } | 266 | } | |
252 | 267 | |||
253 | 268 | |||
254 | STATIC void | 269 | STATIC void | |
255 | setoption(int flag, int val) | 270 | setoption(int flag, int val) | |
256 | { | 271 | { | |
257 | size_t i; | 272 | size_t i; | |
258 | 273 | |||
@@ -356,27 +371,27 @@ shiftcmd(int argc, char **argv) | @@ -356,27 +371,27 @@ shiftcmd(int argc, char **argv) | |||
356 | return 0; | 371 | return 0; | |
357 | } | 372 | } | |
358 | 373 | |||
359 | 374 | |||
360 | 375 | |||
361 | /* | 376 | /* | |
362 | * The set command builtin. | 377 | * The set command builtin. | |
363 | */ | 378 | */ | |
364 | 379 | |||
365 | int | 380 | int | |
366 | setcmd(int argc, char **argv) | 381 | setcmd(int argc, char **argv) | |
367 | { | 382 | { | |
368 | if (argc == 1) | 383 | if (argc == 1) | |
369 | return showvars(0, 0, 1); | 384 | return showvars(0, 0, 1, 0); | |
370 | INTOFF; | 385 | INTOFF; | |
371 | options(0); | 386 | options(0); | |
372 | optschanged(); | 387 | optschanged(); | |
373 | if (*argptr != NULL) { | 388 | if (*argptr != NULL) { | |
374 | setparam(argptr); | 389 | setparam(argptr); | |
375 | } | 390 | } | |
376 | INTON; | 391 | INTON; | |
377 | return 0; | 392 | return 0; | |
378 | } | 393 | } | |
379 | 394 | |||
380 | 395 | |||
381 | void | 396 | void | |
382 | getoptsreset(const char *value) | 397 | getoptsreset(const char *value) |
--- src/bin/sh/options.h 2016/02/23 18:30:16 1.24
+++ src/bin/sh/options.h 2016/03/31 16:16:35 1.25
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: options.h,v 1.24 2016/02/23 18:30:16 christos Exp $ */ | 1 | /* $NetBSD: options.h,v 1.25 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -95,29 +95,31 @@ DEF_OPT( "quietprofile", 'q' ) | @@ -95,29 +95,31 @@ DEF_OPT( "quietprofile", 'q' ) | |||
95 | #define qflag optlist[15].val | 95 | #define qflag optlist[15].val | |
96 | DEF_OPT( "nolog", 0 ) /* [U] no functon defs in command history */ | 96 | DEF_OPT( "nolog", 0 ) /* [U] no functon defs in command history */ | |
97 | #define nolog optlist[16].val | 97 | #define nolog optlist[16].val | |
98 | DEF_OPT( "cdprint", 0 ) /* always print result of cd */ | 98 | DEF_OPT( "cdprint", 0 ) /* always print result of cd */ | |
99 | #define cdprint optlist[17].val | 99 | #define cdprint optlist[17].val | |
100 | DEF_OPT( "tabcomplete", 0 ) /* <tab> causes filename expansion */ | 100 | DEF_OPT( "tabcomplete", 0 ) /* <tab> causes filename expansion */ | |
101 | #define tabcomplete optlist[18].val | 101 | #define tabcomplete optlist[18].val | |
102 | DEF_OPT( "fork", 'F' ) /* use fork(2) instead of vfork(2) */ | 102 | DEF_OPT( "fork", 'F' ) /* use fork(2) instead of vfork(2) */ | |
103 | #define usefork optlist[19].val | 103 | #define usefork optlist[19].val | |
104 | DEF_OPT( "nopriv", 'p' ) /* preserve privs even if set{u,g}id */ | 104 | DEF_OPT( "nopriv", 'p' ) /* preserve privs even if set{u,g}id */ | |
105 | #define pflag optlist[20].val | 105 | #define pflag optlist[20].val | |
106 | DEF_OPT( "trackall", 'h' ) /* [U] locate cmds in funcs when defined */ | 106 | DEF_OPT( "trackall", 'h' ) /* [U] locate cmds in funcs when defined */ | |
107 | #define hflag optlist[21].val | 107 | #define hflag optlist[21].val | |
108 | DEF_OPT( "posix", 0 ) /* operate in posix mode */ | |||
109 | #define posix optlist[22].val | |||
108 | #ifdef DEBUG | 110 | #ifdef DEBUG | |
109 | DEF_OPT( "debug", 0 ) /* enable debug prints */ | 111 | DEF_OPT( "debug", 0 ) /* enable debug prints */ | |
110 | #define debug optlist[22].val | 112 | #define debug optlist[23].val | |
111 | #endif | 113 | #endif | |
112 | 114 | |||
113 | #ifdef DEFINE_OPTIONS | 115 | #ifdef DEFINE_OPTIONS | |
114 | { 0, 0, 0, 0 }, | 116 | { 0, 0, 0, 0 }, | |
115 | }; | 117 | }; | |
116 | #define NOPTS (sizeof optlist / sizeof optlist[0] - 1) | 118 | #define NOPTS (sizeof optlist / sizeof optlist[0] - 1) | |
117 | int sizeof_optlist = sizeof optlist; | 119 | int sizeof_optlist = sizeof optlist; | |
118 | #else | 120 | #else | |
119 | extern struct optent optlist[]; | 121 | extern struct optent optlist[]; | |
120 | extern int sizeof_optlist; | 122 | extern int sizeof_optlist; | |
121 | #endif | 123 | #endif | |
122 | 124 | |||
123 | 125 |
--- src/bin/sh/var.c 2016/03/27 14:34:46 1.48
+++ src/bin/sh/var.c 2016/03/31 16:16:35 1.49
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: var.c,v 1.48 2016/03/27 14:34:46 christos Exp $ */ | 1 | /* $NetBSD: var.c,v 1.49 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | #include <sys/cdefs.h> | 35 | #include <sys/cdefs.h> | |
36 | #ifndef lint | 36 | #ifndef lint | |
37 | #if 0 | 37 | #if 0 | |
38 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; | 38 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; | |
39 | #else | 39 | #else | |
40 | __RCSID("$NetBSD: var.c,v 1.48 2016/03/27 14:34:46 christos Exp $"); | 40 | __RCSID("$NetBSD: var.c,v 1.49 2016/03/31 16:16:35 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | #endif /* not lint */ | 42 | #endif /* not lint */ | |
43 | 43 | |||
44 | #include <unistd.h> | 44 | #include <unistd.h> | |
45 | #include <stdlib.h> | 45 | #include <stdlib.h> | |
46 | #include <string.h> | 46 | #include <string.h> | |
47 | #include <paths.h> | 47 | #include <paths.h> | |
48 | #include <limits.h> | 48 | #include <limits.h> | |
49 | 49 | |||
50 | /* | 50 | /* | |
51 | * Shell variables. | 51 | * Shell variables. | |
52 | */ | 52 | */ | |
53 | 53 | |||
@@ -88,41 +88,44 @@ struct varinit { | @@ -88,41 +88,44 @@ struct varinit { | |||
88 | struct localvar *localvars; | 88 | struct localvar *localvars; | |
89 | 89 | |||
90 | #ifndef SMALL | 90 | #ifndef SMALL | |
91 | struct var vhistsize; | 91 | struct var vhistsize; | |
92 | struct var vterm; | 92 | struct var vterm; | |
93 | #endif | 93 | #endif | |
94 | struct var vifs; | 94 | struct var vifs; | |
95 | struct var vmail; | 95 | struct var vmail; | |
96 | struct var vmpath; | 96 | struct var vmpath; | |
97 | struct var vpath; | 97 | struct var vpath; | |
98 | struct var vps1; | 98 | struct var vps1; | |
99 | struct var vps2; | 99 | struct var vps2; | |
100 | struct var vps4; | 100 | struct var vps4; | |
101 | struct var vvers; | |||
101 | struct var voptind; | 102 | struct var voptind; | |
102 | 103 | |||
103 | char ifs_default[] = " \t\n"; | 104 | char ifs_default[] = " \t\n"; | |
104 | 105 | |||
105 | const struct varinit varinit[] = { | 106 | const struct varinit varinit[] = { | |
106 | #ifndef SMALL | 107 | #ifndef SMALL | |
107 | { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", | 108 | { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", | |
108 | sethistsize }, | 109 | sethistsize }, | |
109 | #endif | 110 | #endif | |
110 | { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", | 111 | { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", | |
111 | NULL }, | 112 | NULL }, | |
112 | { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", | 113 | { &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", | |
113 | NULL }, | 114 | NULL }, | |
114 | { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", | 115 | { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", | |
115 | NULL }, | 116 | NULL }, | |
117 | { &vvers, VSTRFIXED|VTEXTFIXED|VNOEXPORT, "NETBSD_SHELL=", | |||
118 | NULL }, | |||
116 | { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH, | 119 | { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH, | |
117 | changepath }, | 120 | changepath }, | |
118 | /* | 121 | /* | |
119 | * vps1 depends on uid | 122 | * vps1 depends on uid | |
120 | */ | 123 | */ | |
121 | { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", | 124 | { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", | |
122 | NULL }, | 125 | NULL }, | |
123 | { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ", | 126 | { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ", | |
124 | NULL }, | 127 | NULL }, | |
125 | #ifndef SMALL | 128 | #ifndef SMALL | |
126 | { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", | 129 | { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", | |
127 | setterm }, | 130 | setterm }, | |
128 | #endif | 131 | #endif | |
@@ -135,46 +138,48 @@ const struct varinit varinit[] = { | @@ -135,46 +138,48 @@ const struct varinit varinit[] = { | |||
135 | struct var *vartab[VTABSIZE]; | 138 | struct var *vartab[VTABSIZE]; | |
136 | 139 | |||
137 | STATIC int strequal(const char *, const char *); | 140 | STATIC int strequal(const char *, const char *); | |
138 | STATIC struct var *find_var(const char *, struct var ***, int *); | 141 | STATIC struct var *find_var(const char *, struct var ***, int *); | |
139 | 142 | |||
140 | /* | 143 | /* | |
141 | * Initialize the varable symbol tables and import the environment | 144 | * Initialize the varable symbol tables and import the environment | |
142 | */ | 145 | */ | |
143 | 146 | |||
144 | #ifdef mkinit | 147 | #ifdef mkinit | |
145 | INCLUDE <stdio.h> | 148 | INCLUDE <stdio.h> | |
146 | INCLUDE <unistd.h> | 149 | INCLUDE <unistd.h> | |
147 | INCLUDE "var.h" | 150 | INCLUDE "var.h" | |
151 | INCLUDE "version.h" | |||
148 | MKINIT char **environ; | 152 | MKINIT char **environ; | |
149 | INIT { | 153 | INIT { | |
150 | char **envp; | 154 | char **envp; | |
151 | char buf[64]; | 155 | char buf[64]; | |
152 | 156 | |||
153 | initvar(); | 157 | initvar(); | |
154 | for (envp = environ ; *envp ; envp++) { | 158 | for (envp = environ ; *envp ; envp++) { | |
155 | if (strchr(*envp, '=')) { | 159 | if (strchr(*envp, '=')) { | |
156 | setvareq(*envp, VEXPORT|VTEXTFIXED); | 160 | setvareq(*envp, VEXPORT|VTEXTFIXED); | |
157 | } | 161 | } | |
158 | } | 162 | } | |
159 | 163 | |||
160 | /* | 164 | /* | |
161 | * PPID is readonly | 165 | * PPID is readonly | |
162 | * set after processing environ to override anything there | 166 | * set after processing environ to override anything there | |
163 | * Always default IFS, ignore any value from environment. | 167 | * Always default IFS, ignore any value from environment. | |
164 | */ | 168 | */ | |
165 | snprintf(buf, sizeof(buf), "%d", (int)getppid()); | 169 | snprintf(buf, sizeof(buf), "%d", (int)getppid()); | |
166 | setvar("PPID", buf, VREADONLY); | 170 | setvar("PPID", buf, VREADONLY); | |
167 | setvar("IFS", ifs_default, VTEXTFIXED); | 171 | setvar("IFS", ifs_default, VTEXTFIXED); | |
172 | setvar("NETBSD_SHELL", NETBSD_SHELL, VTEXTFIXED|VREADONLY|VNOEXPORT); | |||
168 | } | 173 | } | |
169 | #endif | 174 | #endif | |
170 | 175 | |||
171 | 176 | |||
172 | /* | 177 | /* | |
173 | * This routine initializes the builtin variables. It is called when the | 178 | * This routine initializes the builtin variables. It is called when the | |
174 | * shell is initialized and again when a shell procedure is spawned. | 179 | * shell is initialized and again when a shell procedure is spawned. | |
175 | */ | 180 | */ | |
176 | 181 | |||
177 | void | 182 | void | |
178 | initvar(void) | 183 | initvar(void) | |
179 | { | 184 | { | |
180 | const struct varinit *ip; | 185 | const struct varinit *ip; | |
@@ -284,43 +289,45 @@ setvar(const char *name, const char *val | @@ -284,43 +289,45 @@ setvar(const char *name, const char *val | |||
284 | /* | 289 | /* | |
285 | * Same as setvar except that the variable and value are passed in | 290 | * Same as setvar except that the variable and value are passed in | |
286 | * the first argument as name=value. Since the first argument will | 291 | * the first argument as name=value. Since the first argument will | |
287 | * be actually stored in the table, it should not be a string that | 292 | * be actually stored in the table, it should not be a string that | |
288 | * will go away. | 293 | * will go away. | |
289 | */ | 294 | */ | |
290 | 295 | |||
291 | void | 296 | void | |
292 | setvareq(char *s, int flags) | 297 | setvareq(char *s, int flags) | |
293 | { | 298 | { | |
294 | struct var *vp, **vpp; | 299 | struct var *vp, **vpp; | |
295 | int nlen; | 300 | int nlen; | |
296 | 301 | |||
297 | if (aflag) | 302 | if (aflag && !(flags & VNOEXPORT)) | |
298 | flags |= VEXPORT; | 303 | flags |= VEXPORT; | |
299 | vp = find_var(s, &vpp, &nlen); | 304 | vp = find_var(s, &vpp, &nlen); | |
300 | if (vp != NULL) { | 305 | if (vp != NULL) { | |
301 | if (vp->flags & VREADONLY) | 306 | if (vp->flags & VREADONLY) | |
302 | error("%.*s: is read only", vp->name_len, s); | 307 | error("%.*s: is read only", vp->name_len, s); | |
303 | if (flags & VNOSET) | 308 | if (flags & VNOSET) | |
304 | return; | 309 | return; | |
305 | INTOFF; | 310 | INTOFF; | |
306 | 311 | |||
307 | if (vp->func && (flags & VNOFUNC) == 0) | 312 | if (vp->func && (flags & VNOFUNC) == 0) | |
308 | (*vp->func)(s + vp->name_len + 1); | 313 | (*vp->func)(s + vp->name_len + 1); | |
309 | 314 | |||
310 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) | 315 | if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) | |
311 | ckfree(vp->text); | 316 | ckfree(vp->text); | |
312 | 317 | |||
313 | vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); | 318 | vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); | |
319 | if (flags & VNOEXPORT) | |||
320 | vp->flags &= ~VEXPORT; | |||
314 | vp->flags |= flags & ~VNOFUNC; | 321 | vp->flags |= flags & ~VNOFUNC; | |
315 | vp->text = s; | 322 | vp->text = s; | |
316 | 323 | |||
317 | /* | 324 | /* | |
318 | * We could roll this to a function, to handle it as | 325 | * We could roll this to a function, to handle it as | |
319 | * a regular variable function callback, but why bother? | 326 | * a regular variable function callback, but why bother? | |
320 | */ | 327 | */ | |
321 | if (vp == &vmpath || (vp == &vmail && ! mpathset())) | 328 | if (vp == &vmpath || (vp == &vmail && ! mpathset())) | |
322 | chkmail(1); | 329 | chkmail(1); | |
323 | INTON; | 330 | INTON; | |
324 | return; | 331 | return; | |
325 | } | 332 | } | |
326 | /* not found */ | 333 | /* not found */ | |
@@ -519,27 +526,27 @@ sort_var(const void *v_v1, const void *v | @@ -519,27 +526,27 @@ sort_var(const void *v_v1, const void *v | |||
519 | /* XXX Will anyone notice we include the '=' of the shorter name? */ | 526 | /* XXX Will anyone notice we include the '=' of the shorter name? */ | |
520 | return strcoll((*v1)->text, (*v2)->text); | 527 | return strcoll((*v1)->text, (*v2)->text); | |
521 | } | 528 | } | |
522 | 529 | |||
523 | /* | 530 | /* | |
524 | * POSIX requires that 'set' (but not export or readonly) output the | 531 | * POSIX requires that 'set' (but not export or readonly) output the | |
525 | * variables in lexicographic order - by the locale's collating order (sigh). | 532 | * variables in lexicographic order - by the locale's collating order (sigh). | |
526 | * Maybe we could keep them in an ordered balanced binary tree | 533 | * Maybe we could keep them in an ordered balanced binary tree | |
527 | * instead of hashed lists. | 534 | * instead of hashed lists. | |
528 | * For now just roll 'em through qsort for printing... | 535 | * For now just roll 'em through qsort for printing... | |
529 | */ | 536 | */ | |
530 | 537 | |||
531 | int | 538 | int | |
532 | showvars(const char *name, int flag, int show_value) | 539 | showvars(const char *name, int flag, int show_value, const char *xtra) | |
533 | { | 540 | { | |
534 | struct var **vpp; | 541 | struct var **vpp; | |
535 | struct var *vp; | 542 | struct var *vp; | |
536 | const char *p; | 543 | const char *p; | |
537 | 544 | |||
538 | static struct var **list; /* static in case we are interrupted */ | 545 | static struct var **list; /* static in case we are interrupted */ | |
539 | static int list_len; | 546 | static int list_len; | |
540 | int count = 0; | 547 | int count = 0; | |
541 | 548 | |||
542 | if (!list) { | 549 | if (!list) { | |
543 | list_len = 32; | 550 | list_len = 32; | |
544 | list = ckmalloc(list_len * sizeof *list); | 551 | list = ckmalloc(list_len * sizeof *list); | |
545 | } | 552 | } | |
@@ -555,71 +562,114 @@ showvars(const char *name, int flag, int | @@ -555,71 +562,114 @@ showvars(const char *name, int flag, int | |||
555 | (list_len << 1) * sizeof *list); | 562 | (list_len << 1) * sizeof *list); | |
556 | list_len <<= 1; | 563 | list_len <<= 1; | |
557 | } | 564 | } | |
558 | list[count++] = vp; | 565 | list[count++] = vp; | |
559 | } | 566 | } | |
560 | } | 567 | } | |
561 | 568 | |||
562 | qsort(list, count, sizeof *list, sort_var); | 569 | qsort(list, count, sizeof *list, sort_var); | |
563 | 570 | |||
564 | for (vpp = list; count--; vpp++) { | 571 | for (vpp = list; count--; vpp++) { | |
565 | vp = *vpp; | 572 | vp = *vpp; | |
566 | if (name) | 573 | if (name) | |
567 | out1fmt("%s ", name); | 574 | out1fmt("%s ", name); | |
575 | if (xtra) | |||
576 | out1fmt("%s ", xtra); | |||
568 | for (p = vp->text ; *p != '=' ; p++) | 577 | for (p = vp->text ; *p != '=' ; p++) | |
569 | out1c(*p); | 578 | out1c(*p); | |
570 | if (!(vp->flags & VUNSET) && show_value) { | 579 | if (!(vp->flags & VUNSET) && show_value) { | |
571 | out1fmt("="); | 580 | out1fmt("="); | |
572 | print_quoted(++p); | 581 | print_quoted(++p); | |
573 | } | 582 | } | |
574 | out1c('\n'); | 583 | out1c('\n'); | |
575 | } | 584 | } | |
576 | return 0; | 585 | return 0; | |
577 | } | 586 | } | |
578 | 587 | |||
579 | 588 | |||
580 | 589 | |||
581 | /* | 590 | /* | |
582 | * The export and readonly commands. | 591 | * The export and readonly commands. | |
583 | */ | 592 | */ | |
584 | 593 | |||
585 | int | 594 | int | |
586 | exportcmd(int argc, char **argv) | 595 | exportcmd(int argc, char **argv) | |
587 | { | 596 | { | |
588 | struct var *vp; | 597 | struct var *vp; | |
589 | char *name; | 598 | char *name; | |
590 | const char *p; | 599 | const char *p; | |
591 | int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; | 600 | int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; | |
592 | int pflg; | 601 | int pflg = 0; | |
602 | int nflg = 0; | |||
603 | int xflg = 0; | |||
604 | int res; | |||
605 | int c; | |||
606 | ||||
607 | ||||
608 | while ((c = nextopt("npx")) != '\0') { | |||
609 | switch (c) { | |||
610 | case 'p': | |||
611 | if (nflg) | |||
612 | return 1; | |||
613 | pflg = 3; | |||
614 | break; | |||
615 | case 'n': | |||
616 | if (pflg || xflg || flag == VREADONLY) | |||
617 | return 1; | |||
618 | nflg = 1; | |||
619 | break; | |||
620 | case 'x': | |||
621 | if (nflg || flag == VREADONLY) | |||
622 | return 1; | |||
623 | flag = VNOEXPORT; | |||
624 | xflg = 1; | |||
625 | break; | |||
626 | default: | |||
627 | return 1; | |||
628 | } | |||
629 | } | |||
593 | 630 | |||
594 | pflg = nextopt("p") == 'p' ? 3 : 0; | 631 | if (nflg && *argptr == NULL) | |
595 | if (argc <= 1 || pflg) { | 632 | return 1; | |
596 | showvars( pflg ? argv[0] : 0, flag, pflg ); | 633 | ||
634 | if (pflg || *argptr == NULL) { | |||
635 | showvars( pflg ? argv[0] : 0, flag, pflg, | |||
636 | pflg && xflg ? "-x" : NULL ); | |||
597 | return 0; | 637 | return 0; | |
598 | } | 638 | } | |
599 | 639 | |||
640 | res = 0; | |||
600 | while ((name = *argptr++) != NULL) { | 641 | while ((name = *argptr++) != NULL) { | |
601 | if ((p = strchr(name, '=')) != NULL) { | 642 | if ((p = strchr(name, '=')) != NULL) { | |
602 | p++; | 643 | p++; | |
603 | } else { | 644 | } else { | |
604 | vp = find_var(name, NULL, NULL); | 645 | vp = find_var(name, NULL, NULL); | |
605 | if (vp != NULL) { | 646 | if (vp != NULL) { | |
606 | vp->flags |= flag; | 647 | if (nflg) | |
648 | vp->flags &= ~flag; | |||
649 | else if (flag&VEXPORT && vp->flags&VNOEXPORT) | |||
650 | res = 1; | |||
651 | else { | |||
652 | vp->flags |= flag; | |||
653 | if (flag == VNOEXPORT) | |||
654 | vp->flags &= ~VEXPORT; | |||
655 | } | |||
607 | continue; | 656 | continue; | |
608 | } | 657 | } | |
609 | } | 658 | } | |
610 | setvar(name, p, flag); | 659 | if (!nflg) | |
660 | setvar(name, p, flag); | |||
611 | } | 661 | } | |
612 | return 0; | 662 | return res; | |
613 | } | 663 | } | |
614 | 664 | |||
615 | 665 | |||
616 | /* | 666 | /* | |
617 | * The "local" command. | 667 | * The "local" command. | |
618 | */ | 668 | */ | |
619 | 669 | |||
620 | int | 670 | int | |
621 | localcmd(int argc, char **argv) | 671 | localcmd(int argc, char **argv) | |
622 | { | 672 | { | |
623 | char *name; | 673 | char *name; | |
624 | 674 | |||
625 | if (! in_function()) | 675 | if (! in_function()) | |
@@ -760,27 +810,27 @@ unsetcmd(int argc, char **argv) | @@ -760,27 +810,27 @@ unsetcmd(int argc, char **argv) | |||
760 | * Unset the specified variable. | 810 | * Unset the specified variable. | |
761 | */ | 811 | */ | |
762 | 812 | |||
763 | int | 813 | int | |
764 | unsetvar(const char *s, int unexport) | 814 | unsetvar(const char *s, int unexport) | |
765 | { | 815 | { | |
766 | struct var **vpp; | 816 | struct var **vpp; | |
767 | struct var *vp; | 817 | struct var *vp; | |
768 | 818 | |||
769 | vp = find_var(s, &vpp, NULL); | 819 | vp = find_var(s, &vpp, NULL); | |
770 | if (vp == NULL) | 820 | if (vp == NULL) | |
771 | return 0; | 821 | return 0; | |
772 | 822 | |||
773 | if (vp->flags & VREADONLY) | 823 | if (vp->flags & VREADONLY && !unexport) | |
774 | return 1; | 824 | return 1; | |
775 | 825 | |||
776 | INTOFF; | 826 | INTOFF; | |
777 | if (unexport) { | 827 | if (unexport) { | |
778 | vp->flags &= ~VEXPORT; | 828 | vp->flags &= ~VEXPORT; | |
779 | } else { | 829 | } else { | |
780 | if (vp->text[vp->name_len + 1] != '\0') | 830 | if (vp->text[vp->name_len + 1] != '\0') | |
781 | setvar(s, nullstr, 0); | 831 | setvar(s, nullstr, 0); | |
782 | vp->flags &= ~VEXPORT; | 832 | vp->flags &= ~VEXPORT; | |
783 | vp->flags |= VUNSET; | 833 | vp->flags |= VUNSET; | |
784 | if ((vp->flags & VSTRFIXED) == 0) { | 834 | if ((vp->flags & VSTRFIXED) == 0) { | |
785 | if ((vp->flags & VTEXTFIXED) == 0) | 835 | if ((vp->flags & VTEXTFIXED) == 0) | |
786 | ckfree(vp->text); | 836 | ckfree(vp->text); |
--- src/bin/sh/var.h 2016/03/27 14:34:46 1.27
+++ src/bin/sh/var.h 2016/03/31 16:16:35 1.28
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: var.h,v 1.27 2016/03/27 14:34:46 christos Exp $ */ | 1 | /* $NetBSD: var.h,v 1.28 2016/03/31 16:16:35 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991, 1993 | 4 | * Copyright (c) 1991, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * Kenneth Almquist. | 8 | * Kenneth Almquist. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -29,34 +29,35 @@ | @@ -29,34 +29,35 @@ | |||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | * | 33 | * | |
34 | * @(#)var.h 8.2 (Berkeley) 5/4/95 | 34 | * @(#)var.h 8.2 (Berkeley) 5/4/95 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | /* | 37 | /* | |
38 | * Shell variables. | 38 | * Shell variables. | |
39 | */ | 39 | */ | |
40 | 40 | |||
41 | /* flags */ | 41 | /* flags */ | |
42 | #define VEXPORT 0x01 /* variable is exported */ | 42 | #define VEXPORT 0x0001 /* variable is exported */ | |
43 | #define VREADONLY 0x02 /* variable cannot be modified */ | 43 | #define VREADONLY 0x0002 /* variable cannot be modified */ | |
44 | #define VSTRFIXED 0x04 /* variable struct is statically allocated */ | 44 | #define VSTRFIXED 0x0004 /* variable struct is statically allocated */ | |
45 | #define VTEXTFIXED 0x08 /* text is statically allocated */ | 45 | #define VTEXTFIXED 0x0008 /* text is statically allocated */ | |
46 | #define VSTACK 0x10 /* text is allocated on the stack */ | 46 | #define VSTACK 0x0010 /* text is allocated on the stack */ | |
47 | #define VUNSET 0x20 /* the variable is not set */ | 47 | #define VUNSET 0x0020 /* the variable is not set */ | |
48 | #define VNOFUNC 0x40 /* don't call the callback function */ | 48 | #define VNOFUNC 0x0040 /* don't call the callback function */ | |
49 | #define VNOSET 0x80 /* do not set variable - just readonly test */ | 49 | #define VNOSET 0x0080 /* do not set variable - just readonly test */ | |
50 | #define VNOEXPORT 0x0100 /* variable may not be exported */ | |||
50 | 51 | |||
51 | 52 | |||
52 | struct var { | 53 | struct var { | |
53 | struct var *next; /* next entry in hash list */ | 54 | struct var *next; /* next entry in hash list */ | |
54 | int flags; /* flags are defined above */ | 55 | int flags; /* flags are defined above */ | |
55 | char *text; /* name=value */ | 56 | char *text; /* name=value */ | |
56 | int name_len; /* length of name */ | 57 | int name_len; /* length of name */ | |
57 | void (*func)(const char *); | 58 | void (*func)(const char *); | |
58 | /* function to be called when */ | 59 | /* function to be called when */ | |
59 | /* the variable gets set/unset */ | 60 | /* the variable gets set/unset */ | |
60 | }; | 61 | }; | |
61 | 62 | |||
62 | 63 | |||
@@ -105,21 +106,21 @@ extern struct var vhistsize; | @@ -105,21 +106,21 @@ extern struct var vhistsize; | |||
105 | #endif | 106 | #endif | |
106 | 107 | |||
107 | #define mpathset() ((vmpath.flags & VUNSET) == 0) | 108 | #define mpathset() ((vmpath.flags & VUNSET) == 0) | |
108 | 109 | |||
109 | void initvar(void); | 110 | void initvar(void); | |
110 | void setvar(const char *, const char *, int); | 111 | void setvar(const char *, const char *, int); | |
111 | void setvareq(char *, int); | 112 | void setvareq(char *, int); | |
112 | struct strlist; | 113 | struct strlist; | |
113 | void listsetvar(struct strlist *, int); | 114 | void listsetvar(struct strlist *, int); | |
114 | char *lookupvar(const char *); | 115 | char *lookupvar(const char *); | |
115 | char *bltinlookup(const char *, int); | 116 | char *bltinlookup(const char *, int); | |
116 | char **environment(void); | 117 | char **environment(void); | |
117 | void shprocvar(void); | 118 | void shprocvar(void); | |
118 | int showvars(const char *, int, int); | 119 | int showvars(const char *, int, int, const char *); | |
119 | void mklocal(const char *, int); | 120 | void mklocal(const char *, int); | |
120 | void listmklocal(struct strlist *, int); | 121 | void listmklocal(struct strlist *, int); | |
121 | void poplocalvars(void); | 122 | void poplocalvars(void); | |
122 | int unsetvar(const char *, int); | 123 | int unsetvar(const char *, int); | |
123 | void choose_ps1(void); | 124 | void choose_ps1(void); | |
124 | int setvarsafe(const char *, const char *, int); | 125 | int setvarsafe(const char *, const char *, int); | |
125 | void print_quoted(const char *); | 126 | void print_quoted(const char *); |
/* $NetBSD: version.h,v 1.1 2016/03/31 16:16:35 christos Exp $ */
/*-
* Copyright (c) 2016
* The NetBSD Foundation. Rights and Wrongs all Irrelevant.
*
* Redistribution and use in source and binary forms, with and without
* modification, are required provided that the following conditions
* are met:
* 1. Redistributions of source code must remove the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must not reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* small print and/or other shit provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE FOUNDATION AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Should these conditions be unacceptable, go soak your big toe in a
* bowl of lemon juice, then suck on it.
*/
/*
* This value should be modified rarely - only when significant changes
* to the shell (which does not mean a bug fixed, or some new feature added)
* have been made. The most likely reason to change this value would be
* when a new (shell only) release is to be exported. This should not be
* updated just because a new NetBSD release is to include this code.
*/
#define NETBSD_SHELL "20160401"