- Timestamp:
- Sep 10, 2020, 2:47:29 AM (5 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/parser.c
r3438 r3439 1897 1897 ret->nfile.next = copyparsetree(psh, src->nfile.next); 1898 1898 ret->nfile.fname = copyparsetree(psh, src->nfile.fname); 1899 /** @todo complicated, we should copy it in some contexts but no all. sigh. */ 1899 1900 ret->nfile.expfname = stsavestr(psh, src->nfile.expfname); 1900 1901 break; -
trunk/src/kash/shfile.c
r3438 r3439 99 99 { 100 100 ULONG Attributes; 101 102 103 104 105 106 107 108 109 110 101 ACCESS_MASK GrantedAccess; 102 ULONG HandleCount; 103 ULONG PointerCount; 104 ULONG PagedPoolUsage; 105 ULONG NonPagedPoolUsage; 106 ULONG Reserved[3]; 107 ULONG NameInformationLength; 108 ULONG TypeInformationLength; 109 ULONG SecurityDescriptorLength; 110 LARGE_INTEGER CreateTime; 111 111 } MY_OBJECT_BASIC_INFORMATION; 112 112 … … 910 910 } 911 911 912 /** 913 * Deletes the file descriptor table. 914 * 915 * Safe to call more than once. 916 */ 917 void shfile_uninit(shfdtab *pfdtab) 918 { 919 if (!pfdtab) 920 return; 921 922 if (pfdtab->tab) 923 { 924 unsigned left = pfdtab->size; 925 struct shfile *pfd = pfdtab->tab; 926 while (left-- > 0) 927 { 928 if (pfd->fd != -1) 929 { 930 #if K_OS == K_OS_WINDOWS 931 BOOL rc = CloseHandle((HANDLE)pfd->native); 932 assert(rc == TRUE); K_NOREF(rc); 933 #else 934 int rc = close((int)pfd->native); 935 assert(rc == 0); K_NOREF(rc); 936 #endif 937 pfd->fd = -1; 938 pfd->native = -1; 939 } 940 pfd++; 941 } 942 943 sh_free(NULL, pfdtab->tab); 944 pfdtab->tab = NULL; 945 } 946 947 shmtx_delete(&pfdtab->mtx); 948 949 sh_free(NULL, pfdtab->cwd); 950 pfdtab->cwd = NULL; 951 } 952 912 953 #if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE) 913 954 … … 956 997 } 957 998 999 # ifdef SH_FORKED_MODE 958 1000 /** 959 1001 * Helper for shfork. … … 1000 1042 shmtx_leave(&pfdtab->mtx, &tmp); 1001 1043 } 1044 # endif /* SH_FORKED_MODE */ 1002 1045 1003 1046 /** -
trunk/src/kash/shfile.h
r2546 r3439 131 131 132 132 int shfile_init(shfdtab *, shfdtab *); 133 void shfile_uninit(shfdtab *); 133 134 void shfile_fork_win(shfdtab *pfdtab, int set, intptr_t *hndls); 134 135 void *shfile_exec_win(shfdtab *pfdtab, int prepare, unsigned short *sizep, intptr_t *hndls); -
trunk/src/kash/shinstance.c
r3438 r3439 26 26 */ 27 27 28 /******************************************************************************* 29 * Header Files * 30 *******************************************************************************/ 28 29 /********************************************************************************************************************************* 30 * Header Files * 31 *********************************************************************************************************************************/ 31 32 #include <string.h> 32 33 #include <stdlib.h> … … 41 42 42 43 #include "alias.h" 44 #include "error.h" 43 45 #include "memalloc.h" 44 46 #include "shell.h" … … 53 55 54 56 55 /******************************************************************************* 56 * Global Variables * 57 *******************************************************************************/ 57 /********************************************************************************************************************************* 58 * Defined Constants And Macros * 59 *********************************************************************************************************************************/ 60 #ifndef SH_FORKED_MODE 61 /** Used by sh__exit/sh_thread_wrapper for passing zero via longjmp. */ 62 # define SH_EXIT_ZERO 0x0d15ea5e 63 #endif 64 65 66 /********************************************************************************************************************************* 67 * Global Variables * 68 *********************************************************************************************************************************/ 58 69 /** The mutex protecting the the globals and some shell instance members (sigs). */ 59 70 static shmtx g_sh_mtx; … … 93 104 94 105 106 /** Magic mutex value (final u64). 107 * This is used to detect whether the mutex has been initialized or not, 108 * allowing shmtx_delete to be called more than once without doing harm. 109 * @internal */ 110 #define SHMTX_MAGIC KU64_C(0x8888000019641018) /**< Charles Stross */ 111 /** Index into shmtx::au64 of the SHMTX_MAGIC value. 112 * @internal */ 113 #define SHMTX_MAGIC_IDX (sizeof(shmtx) / sizeof(KU64) - 1) 114 95 115 int shmtx_init(shmtx *pmtx) 96 116 { 117 #if K_OS == K_OS_WINDOWS 118 typedef int mtxsizecheck[sizeof(CRITICAL_SECTION) + sizeof(KU64) <= sizeof(*pmtx) ? 2 : 0]; 119 InitializeCriticalSection((CRITICAL_SECTION *)pmtx); 120 #else 97 121 pmtx->b[0] = 0; 122 #endif 123 pmtx->au64[SHMTX_MAGIC_IDX] = SHMTX_MAGIC; 98 124 return 0; 99 125 } 100 126 127 /** 128 * Safe to call more than once. 129 */ 101 130 void shmtx_delete(shmtx *pmtx) 102 131 { 103 pmtx->b[0] = 0; 132 if (pmtx->au64[SHMTX_MAGIC_IDX] != SHMTX_MAGIC) 133 { 134 #if K_OS == K_OS_WINDOWS 135 DeleteCriticalSection((CRITICAL_SECTION *)pmtx); 136 #else 137 pmtx->b[0] = 0; 138 #endif 139 pmtx->au64[SHMTX_MAGIC_IDX] = ~SHMTX_MAGIC; 140 } 104 141 } 105 142 106 143 void shmtx_enter(shmtx *pmtx, shmtxtmp *ptmp) 107 144 { 145 #if K_OS == K_OS_WINDOWS 146 EnterCriticalSection((CRITICAL_SECTION *)pmtx); 147 ptmp->i = 0x42; 148 #else 108 149 pmtx->b[0] = 0; 109 150 ptmp->i = 0; 151 #endif 110 152 } 111 153 112 154 void shmtx_leave(shmtx *pmtx, shmtxtmp *ptmp) 113 155 { 156 #if K_OS == K_OS_WINDOWS 157 assert(ptmp->i == 0x42); 158 LeaveCriticalSection((CRITICAL_SECTION *)pmtx); 159 ptmp->i = 0x21; 160 #else 114 161 pmtx->b[0] = 0; 115 162 ptmp->i = 432; 163 #endif 116 164 } 117 165 … … 139 187 g_num_shells++; 140 188 189 psh->linked = 1; 190 141 191 shmtx_leave(&g_sh_mtx, &tmp); 142 192 } 143 193 144 #if 0145 194 /** 146 195 * Unlink the shell instance. … … 150 199 static void sh_int_unlink(shinstance *psh) 151 200 { 152 shmtxtmp tmp; 153 shmtx_enter(&g_sh_mtx, &tmp); 154 155 g_num_shells--; 156 157 if (g_sh_tail == psh) 158 g_sh_tail = psh->prev; 159 else 160 psh->next->prev = psh->prev; 161 162 if (g_sh_head == psh) 163 g_sh_head = psh->next; 164 else 165 psh->prev->next = psh->next; 166 167 if (g_sh_root == psh) 168 g_sh_root = 0; 169 170 shmtx_leave(&g_sh_mtx, &tmp); 171 } 172 #endif 201 if (psh->linked) 202 { 203 shinstance *pshcur; 204 shmtxtmp tmp; 205 shmtx_enter(&g_sh_mtx, &tmp); 206 207 g_num_shells--; 208 209 if (g_sh_tail == psh) 210 g_sh_tail = psh->prev; 211 else 212 psh->next->prev = psh->prev; 213 214 if (g_sh_head == psh) 215 g_sh_head = psh->next; 216 else 217 psh->prev->next = psh->next; 218 219 if (g_sh_root == psh) 220 g_sh_root = NULL; 221 222 /* Orphan children: */ 223 for (pshcur = g_sh_head; pshcur; pshcur = pshcur->next) 224 if (pshcur->parent == psh) 225 pshcur->parent = NULL; 226 227 shmtx_leave(&g_sh_mtx, &tmp); 228 } 229 } 230 231 /** 232 * Frees a string vector like environ or argv. 233 * 234 * @param psh The shell to associate the deallocations with. 235 * @param vecp Pointer to the vector pointer. 236 */ 237 static void sh_free_string_vector(shinstance *psh, char ***vecp) 238 { 239 char **vec = *vecp; 240 if (vec) 241 { 242 char *str; 243 size_t i = 0; 244 while ((str = vec[i]) != NULL) 245 { 246 sh_free(psh, str); 247 vec[i] = NULL; 248 i++; 249 } 250 251 sh_free(psh, vec); 252 *vecp = NULL; 253 } 254 } 255 173 256 174 257 /** … … 178 261 * 179 262 * @param psh The shell instance to be destroyed. 263 * @note invalidate thread arguments. 180 264 */ 181 265 static void sh_destroy(shinstance *psh) 182 266 { 267 unsigned left, i; 268 269 sh_int_unlink(psh); 270 shfile_uninit(&psh->fdtab); 271 sh_free_string_vector(psh, &psh->shenviron); 272 273 /** @todo children. */ 274 sh_free(psh, psh->threadarg); 275 psh->threadarg = NULL; 276 277 /* alias.c */ 278 left = psh->aliases; 279 if (left > 0) 280 for (i = 0; i < K_ELEMENTS(psh->atab); i++) 281 { 282 struct alias *cur = psh->atab[i]; 283 if (cur) 284 { 285 do 286 { 287 struct alias *next = cur->next; 288 sh_free(psh, cur->val); 289 sh_free(psh, cur->name); 290 sh_free(psh, cur); 291 cur = next; 292 left--; 293 } while (cur); 294 psh->atab[i] = NULL; 295 if (!left) 296 break; 297 } 298 } 299 300 /* cd.c */ 301 sh_free(psh, psh->curdir); 302 psh->curdir = NULL; 303 sh_free(psh, psh->prevdir); 304 psh->prevdir = NULL; 305 psh->cdcomppath = NULL; /* stalloc */ 306 307 /* eval.h */ 308 if (psh->commandnamemalloc) 309 sh_free(psh, psh->commandname); 310 psh->commandname = NULL; 311 psh->cmdenviron = NULL; 312 313 #if 0 314 /* expand.c */ 315 char *expdest; /**< output of current string */ 316 struct nodelist *argbackq; /**< list of back quote expressions */ 317 struct ifsregion ifsfirst; /**< first struct in list of ifs regions */ 318 struct ifsregion *ifslastp; /**< last struct in list */ 319 struct arglist exparg; /**< holds expanded arg list */ 320 char *expdir; /**< Used by expandmeta. */ 321 322 /* exec.h */ 323 const char *pathopt; /**< set by padvance */ 324 325 /* exec.c */ 326 struct tblentry *cmdtable[CMDTABLESIZE]; 327 int builtinloc/* = -1*/; /**< index in path of %builtin, or -1 */ 328 329 /* input.h */ 330 int plinno/* = 1 */;/**< input line number */ 331 int parsenleft; /**< number of characters left in input buffer */ 332 char *parsenextc; /**< next character in input buffer */ 333 int init_editline/* = 0 */; /**< 0 == not setup, 1 == OK, -1 == failed */ 334 335 /* input.c */ 336 int parselleft; /**< copy of parsefile->lleft */ 337 struct parsefile basepf; /**< top level input file */ 338 char basebuf[BUFSIZ];/**< buffer for top level input file */ 339 struct parsefile *parsefile/* = &basepf*/; /**< current input file */ 340 #ifndef SMALL 341 EditLine *el; /**< cookie for editline package */ 342 #endif 343 344 /* jobs.h */ 345 shpid backgndpid/* = -1 */; /**< pid of last background process */ 346 int job_warning; /**< user was warned about stopped jobs */ 347 348 /* jobs.c */ 349 struct job *jobtab; /**< array of jobs */ 350 int njobs; /**< size of array */ 351 int jobs_invalid; /**< set in child */ 352 shpid initialpgrp; /**< pgrp of shell on invocation */ 353 int curjob/* = -1*/;/**< current job */ 354 int ttyfd/* = -1*/; 355 int jobctl; /**< job control enabled / disabled */ 356 char *cmdnextc; 357 int cmdnleft; 358 359 360 /* mail.c */ 361 #define MAXMBOXES 10 362 int nmboxes; /**< number of mailboxes */ 363 time_t mailtime[MAXMBOXES]; /**< times of mailboxes */ 364 365 /* main.h */ 366 shpid rootpid; /**< pid of main shell. */ 367 int rootshell; /**< true if we aren't a child of the main shell. */ 368 struct shinstance *psh_rootshell; /**< The root shell pointer. (!rootshell) */ 369 370 /* memalloc.h */ 371 char *stacknxt/* = stackbase.space*/; 372 int stacknleft/* = MINSIZE*/; 373 int sstrnleft; 374 int herefd/* = -1 */; 375 376 /* memalloc.c */ 377 struct stack_block stackbase; 378 struct stack_block *stackp/* = &stackbase*/; 379 struct stackmark *markp; 380 381 /* myhistedit.h */ 382 int displayhist; 383 #ifndef SMALL 384 History *hist; 385 EditLine *el; 386 #endif 387 388 /* output.h */ 389 struct output output; 390 struct output errout; 391 struct output memout; 392 struct output *out1; 393 struct output *out2; 394 395 /* output.c */ 396 #define OUTBUFSIZ BUFSIZ 397 #define MEM_OUT -3 /**< output to dynamically allocated memory */ 398 399 /* options.h */ 400 struct optent optlist[NOPTS]; 401 char *minusc; /**< argument to -c option */ 402 char *arg0; /**< $0 */ 403 struct shparam shellparam; /**< $@ */ 404 char **argptr; /**< argument list for builtin commands */ 405 char *optionarg; /**< set by nextopt */ 406 char *optptr; /**< used by nextopt */ 407 char **orgargv; /**< The original argument vector (for cleanup). */ 408 int arg0malloc; /**< Indicates whether arg0 was allocated or is part of orgargv. */ 409 410 /* parse.h */ 411 int tokpushback; 412 int whichprompt; /**< 1 == PS1, 2 == PS2 */ 413 414 /* parser.c */ 415 int noalias/* = 0*/;/**< when set, don't handle aliases */ 416 struct heredoc *heredoclist; /**< list of here documents to read */ 417 int parsebackquote; /**< nonzero if we are inside backquotes */ 418 int doprompt; /**< if set, prompt the user */ 419 int needprompt; /**< true if interactive and at start of line */ 420 int lasttoken; /**< last token read */ 421 char *wordtext; /**< text of last word returned by readtoken */ 422 int checkkwd; /**< 1 == check for kwds, 2 == also eat newlines */ 423 struct nodelist *backquotelist; 424 union node *redirnode; 425 struct heredoc *heredoc; 426 int quoteflag; /**< set if (part of) last token was quoted */ 427 int startlinno; /**< line # where last token started */ 428 429 /* redir.c */ 430 struct redirtab *redirlist; 431 int fd0_redirected/* = 0*/; 432 433 /* show.c */ 434 char tracebuf[1024]; 435 size_t tracepos; 436 int tracefd; 437 438 /* trap.h */ 439 int pendingsigs; /**< indicates some signal received */ 440 441 /* trap.c */ 442 char gotsig[NSIG]; /**< indicates specified signal received */ 443 char *trap[NSIG+1]; /**< trap handler commands */ 444 char sigmode[NSIG]; /**< current value of signal */ 445 446 /* var.h */ 447 struct localvar *localvars; 448 struct var vatty; 449 struct var vifs; 450 struct var vmail; 451 struct var vmpath; 452 struct var vpath; 453 #ifdef _MSC_VER 454 struct var vpath2; 455 #endif 456 struct var vps1; 457 struct var vps2; 458 struct var vps4; 459 #ifndef SMALL 460 struct var vterm; 461 struct var vhistsize; 462 #endif 463 struct var voptind; 464 #ifdef PC_OS2_LIBPATHS 465 struct var libpath_vars[4]; 466 #endif 467 #ifdef SMALL 468 # define VTABSIZE 39 469 #else 470 # define VTABSIZE 517 471 #endif 472 struct var *vartab[VTABSIZE]; 473 474 /* builtins.h */ 475 476 /* bltin/test.c */ 477 char **t_wp; 478 struct t_op const *t_wp_op; 479 #endif 480 183 481 /** @todo finish this... */ 184 482 memset(psh, 0, sizeof(*psh)); … … 196 494 static int sh_clone_string_vector(shinstance *psh, char ***dstp, char **src) 197 495 { 198 char **dst;199 size_t items;200 201 /* count first */202 items = 0;203 while (src[items])204 items++;205 206 /* alloc clone array. */207 *dstp = dst = sh_malloc(psh, sizeof(*dst) * (items + 1));208 if (!dst)209 return -1;210 211 /* copy the items */212 dst[items] = NULL;213 while (items-- > 0)214 {215 dst[items] = sh_strdup(psh, src[items]);216 if (!dst[items])217 {218 /* allocation error, clean up. */219 while (dst[++items])220 sh_free(psh, dst[items]);221 sh_free(psh, dst);222 errno = ENOMEM;223 return -1;224 }225 }226 227 return 0;496 char **dst; 497 size_t items; 498 499 /* count first */ 500 items = 0; 501 while (src[items]) 502 items++; 503 504 /* alloc clone array. */ 505 *dstp = dst = sh_malloc(psh, sizeof(*dst) * (items + 1)); 506 if (!dst) 507 return -1; 508 509 /* copy the items */ 510 dst[items] = NULL; 511 while (items-- > 0) 512 { 513 dst[items] = sh_strdup(psh, src[items]); 514 if (!dst[items]) 515 { 516 /* allocation error, clean up. */ 517 while (dst[++items]) 518 sh_free(psh, dst[items]); 519 sh_free(psh, dst); 520 errno = ENOMEM; 521 return -1; 522 } 523 } 524 525 return 0; 228 526 } 229 527 … … 338 636 shinstance *sh_create_root_shell(char **argv, char **envp) 339 637 { 340 shinstance *psh = sh_create_shell_common(argv, envp, NULL /*parentfdtab*/); 638 shinstance *psh; 639 640 assert(g_sh_mtx.au64[SHMTX_MAGIC_IDX] != SHMTX_MAGIC); 641 shmtx_init(&g_sh_mtx); 642 643 psh = sh_create_shell_common(argv, envp, NULL /*parentfdtab*/); 341 644 if (psh) 342 645 { … … 1049 1352 { 1050 1353 /* get a free table entry. */ 1051 inti = psh->num_children++;1354 unsigned i = psh->num_children++; 1052 1355 if (!(i % 32)) 1053 1356 { … … 1118 1421 static unsigned __stdcall sh_thread_wrapper(void *user) 1119 1422 { 1423 shinstance * volatile volpsh = (shinstance *)user; 1120 1424 shinstance *psh = (shinstance *)user; 1425 struct jmploc exitjmp; 1121 1426 int iExit; 1122 1427 … … 1133 1438 1134 1439 TRACE2((psh, "sh_thread_wrapper: enter\n")); 1135 iExit = psh->thread(psh, psh->threadarg); 1136 /** @todo do shell cleanup. */ 1440 if ((iExit = setjmp(exitjmp.loc)) == 0) 1441 { 1442 psh->exitjmp = &exitjmp; 1443 iExit = psh->thread(psh, psh->threadarg); 1444 TRACE2((psh, "sh_thread_wrapper: thread proc returns %d (%#x)\n", iExit, iExit)); 1445 } 1446 else 1447 { 1448 psh = volpsh; /* paranoia */ 1449 psh->exitjmp = NULL; 1450 TRACE2((psh, "sh_thread_wrapper: longjmp: iExit=%d (%#x)\n", iExit, iExit)); 1451 if (iExit == SH_EXIT_ZERO) 1452 iExit = 0; 1453 } 1454 1455 /* destroy the shell instance and exit the thread. */ 1137 1456 TRACE2((psh, "sh_thread_wrapper: quits - iExit=%d\n", iExit)); 1138 1457 sh_destroy(psh); 1458 shthread_set_shell(NULL); 1139 1459 _endthreadex(iExit); 1140 1460 return iExit; … … 1179 1499 shpid sh_waitpid(shinstance *psh, shpid pid, int *statusp, int flags) 1180 1500 { 1181 shpid pidret;1501 shpid pidret; 1182 1502 #if K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE) 1183 DWORD dwRet;1184 HANDLE hChild = INVALID_HANDLE_VALUE;1185 inti;1503 DWORD dwRet; 1504 HANDLE hChild = INVALID_HANDLE_VALUE; 1505 unsigned i; 1186 1506 1187 1507 *statusp = 0; … … 1204 1524 else if (dwRet == WAIT_TIMEOUT) 1205 1525 { 1206 i = -1; /* don't try close anything */1526 i = ~0; /* don't try close anything */ 1207 1527 pidret = 0; 1208 1528 } … … 1222 1542 flags & WNOHANG ? 0 : INFINITE); 1223 1543 i = dwRet - WAIT_OBJECT_0; 1224 if ( (unsigned)i < (unsigned)psh->num_children)1544 if (i < psh->num_children) 1225 1545 { 1226 1546 hChild = psh->children[i].hChild; … … 1228 1548 else if (dwRet == WAIT_TIMEOUT) 1229 1549 { 1230 i = -1; /* don't try close anything */1550 i = ~0; /* don't try close anything */ 1231 1551 pidret = 0; 1232 1552 } 1233 1553 else 1234 1554 { 1235 i = -1; /* don't try close anything */1555 i = ~0; /* don't try close anything */ 1236 1556 errno = EINVAL; 1237 1557 } … … 1240 1560 { 1241 1561 fprintf(stderr, "panic! too many children!\n"); 1242 i = -1;1562 i = ~0; 1243 1563 *(char *)1 = '\0'; /** @todo implement this! */ 1244 1564 } … … 1247 1567 * Close the handle, and if we succeeded collect the exit code first. 1248 1568 */ 1249 if ( i >= 0 1250 && i < psh->num_children) 1569 if (i < psh->num_children) 1251 1570 { 1252 1571 if (hChild != INVALID_HANDLE_VALUE) … … 1297 1616 { 1298 1617 TRACE2((psh, "sh__exit(%d)\n", rc)); 1299 (void)psh;1300 1618 1301 1619 #if defined(SH_FORKED_MODE) 1302 1620 _exit(rc); 1303 1304 #else 1621 (void)psh; 1622 1623 #else 1624 psh->exitstatus = rc; 1625 1626 /* 1627 * If we're a thread, jump to the sh_thread_wrapper and make a clean exit. 1628 */ 1629 if (psh->thread) 1630 { 1631 if (psh->exitjmp) 1632 longjmp(psh->exitjmp->loc, !rc ? SH_EXIT_ZERO : rc); 1633 else 1634 { 1635 static char const s_msg[] = "fatal error in sh__exit: exitjmp is NULL!\n"; 1636 shfile_write(&psh->fdtab, 2, s_msg, sizeof(s_msg) - 1); 1637 _exit(rc); 1638 } 1639 } 1640 1641 /* 1642 * The main thread will typically have to stick around till all subshell 1643 * threads have been stopped. We must tear down this shell instance as 1644 * much as possible before doing this, though, as subshells could be 1645 * waiting for pipes and such to be closed before they're willing to exit. 1646 */ 1647 if (g_num_shells > 1) 1648 { 1649 TRACE2((psh, "sh__exit: %u shells around, must wait...\n", g_num_shells)); 1650 shfile_uninit(&psh->fdtab); 1651 sh_int_unlink(psh); 1652 } 1653 1654 _exit(rc); 1305 1655 #endif 1306 1656 } -
trunk/src/kash/shinstance.h
r3438 r3439 150 150 shsigset_t sigmask; /**< Our signal mask. */ 151 151 char **shenviron; /**< The environment vector. */ 152 int num_children; /**< Number of children in the array. */ 152 int linked; /**< Set if we're still linked. */ 153 unsigned num_children; /**< Number of children in the array. */ 153 154 shchild *children; /**< The child array. */ 154 155 #ifndef SH_FORKED_MODE 155 156 int (*thread)(struct shinstance *, void *); /**< The thread procedure. */ 156 157 void *threadarg; /**< The thread argument. */ 158 struct jmploc *exitjmp; /**< Long jump target in sh_thread_wrapper for use by sh__exit. */ 157 159 #endif 158 160 … … 165 167 char *curdir; /**< current working directory */ 166 168 char *prevdir; /**< previous working directory */ 167 char *cdcomppath; 169 char *cdcomppath; /**< (stalloc) */ 168 170 int getpwd_first; /**< static in getpwd. (initialized to 1!) */ 169 171 … … 182 184 int exitstatus; /**< exit status of last command */ 183 185 int back_exitstatus;/**< exit status of backquoted command */ 184 struct strlist *cmdenviron; /**< environment for builtin command */186 struct strlist *cmdenviron; /**< environment for builtin command (varlist from evalcommand()) */ 185 187 int funcnest; /**< depth of function calls */ 186 188 int evalskip; /**< set if we are skipping commands */ … … 354 356 char **t_wp; 355 357 struct t_op const *t_wp_op; 356 357 358 }; 358 359 -
trunk/src/kash/shthread.h
r2413 r3439 33 33 { 34 34 char b[64]; 35 KU64 au64[64/sizeof(KU64)]; 36 void *aptrs[64/sizeof(void *)]; 35 37 } shmtx; 36 38
Note:
See TracChangeset
for help on using the changeset viewer.