Changeset 3438 for trunk/src/kash/options.c
- Timestamp:
- Sep 9, 2020, 10:01:39 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/options.c
r2652 r3438 41 41 #endif 42 42 43 #include <assert.h> 43 44 #include <stdlib.h> 44 45 … … 77 78 STATIC int getopts(shinstance *, char *, char *, char **, char ***, char **); 78 79 80 #ifndef SH_FORKED_MODE 81 void 82 subshellinitoptions(shinstance *psh, shinstance *inherit) 83 { 84 unsigned i; 85 int left; 86 const char *arg; 87 memcpy(&psh->optlist[0], &inherit->optlist[0], sizeof(psh->optlist)); 88 89 /** @todo opimize: skip this when executing builtins. */ 90 /* Whether the subshell uses argptr/shellparam/arg0 or replaces them depends 91 on whether the shell will execute a builtin command or not. 92 93 orgargv is already set by the shinstance.c core code, scan the original 94 again and update arg0, shellparm, argptr and optptr. */ 95 96 /* arg0 is either something from orgargv, or in the EXSHELLPROC case a 97 separate allocation that we need to dupe here. The (new) arg0malloc 98 flag indicates which. */ 99 i = 0; 100 psh->arg0malloc = inherit->arg0malloc; 101 if (inherit->arg0malloc) { 102 psh->arg0 = savestr(psh, inherit->arg0); 103 } else { 104 while ((arg = inherit->orgargv[i]) != NULL) { 105 if (inherit->arg0 == arg) { 106 psh->arg0 = psh->orgargv[i]; 107 break; 108 } 109 i++; 110 } 111 assert(psh->arg0 != NULL); 112 } 113 114 /* eval.h's commandname is same as arg0 when set unless we're doing a dot-include. */ 115 if (inherit->commandname) { 116 if (inherit->commandname == inherit->arg0) { 117 psh->commandname = psh->arg0; 118 } else { 119 psh->commandname = savestr(psh, inherit->commandname); 120 psh->commandnamemalloc = 1; 121 } 122 } 123 124 /* shellparam is either pointing right after arg0 in orgargv, though it may 125 also be a separately allocated thing (see setparam), or pointing to the 126 arguments of a shell function we're executing (see eval.c). All in all, 127 it's simpler if we just copy the whole darn thing, ASSUMING no 128 modifications will be made that are needed to be visible elsewhere. 129 */ 130 psh->shellparam.malloc = 1; 131 psh->shellparam.reset = inherit->shellparam.reset; 132 psh->shellparam.nparam = left = inherit->shellparam.nparam; 133 assert(left >= 0); 134 psh->shellparam.p = (char **)ckmalloc(psh, left + 1); 135 psh->shellparam.p[left] = NULL; 136 while (left-- > 0) { 137 arg = inherit->shellparam.p[left]; 138 psh->shellparam.p[left] = savestr(psh, arg); 139 } 140 141 /* The shellparam.optnext member is either NULL or points to a 'p' entry. */ 142 if (inherit->shellparam.optnext) { 143 size_t idx = (size_t)(inherit->shellparam.optnext - inherit->shellparam.p); 144 assert(idx <= inherit->shellparam.nparam); 145 if (idx <= inherit->shellparam.nparam) 146 psh->shellparam.optnext = &psh->shellparam.p[idx]; 147 } 148 149 /* The shellparam.optptr member is either NULL or points within argument 150 prior to shellparam.optnext. We can leave it as NULL if at the EOS. */ 151 if (inherit->shellparam.optptr && *inherit->shellparam.optptr != '\0') { 152 intptr_t idx; 153 if (!inherit->shellparam.optnext || inherit->shellparam.optnext == inherit->shellparam.p) 154 idx = (intptr_t)(inherit->shellparam.nparam - 1); 155 else { 156 idx = (intptr_t)(inherit->shellparam.optnext - inherit->shellparam.p - 1); 157 if (idx > inherit->shellparam.nparam) 158 idx = inherit->shellparam.nparam - 1; 159 } 160 while (idx >= 0) { 161 size_t arglen, off; 162 arg = inherit->shellparam.p[idx]; 163 arglen = strlen(arg); 164 off = (size_t)(inherit->shellparam.optptr - arg); 165 if (off < arglen) { 166 psh->shellparam.optptr = psh->shellparam.p[idx] + off; 167 break; 168 } 169 off--; 170 } 171 assert(psh->shellparam.optptr != NULL); 172 } 173 174 /* minusc: only used in main.c, so not applicable to subshells. */ 175 /* optionarg: only used by callers of nextopt, so not relevant when forking subhells. */ 176 } 177 #endif /* SH_FORKED_MODE */ 178 79 179 80 180 /* … … 105 205 debug(psh) = 1; 106 206 #endif 207 psh->commandnamemalloc = 0; 208 psh->arg0malloc = 0; 107 209 psh->arg0 = argv[0]; 108 210 if (sflag(psh) == 0 && psh->minusc == NULL) {
Note:
See TracChangeset
for help on using the changeset viewer.