- Timestamp:
- Sep 16, 2020 9:18:31 PM (5 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/eval.c
r3458 r3475 1012 1012 exitshell(psh, psh->exitstatus); 1013 1013 } 1014 if (savecmdnamemalloc)1014 else if (savecmdnamemalloc) 1015 1015 sh_free(psh, savecmdname); 1016 1016 if (e != -1) { … … 1041 1041 setvareq(psh, sp->text, VEXPORT|VSTACK); 1042 1042 envp = environment(psh); 1043 shellexec(psh, args->argv, envp, args->path, args->cmdentry.u.index); 1043 shellexec(psh, args->argv, envp, args->path, 1044 args->cmdentry.u.n.index, args->cmdentry.u.n.suffix); 1044 1045 break; 1045 1046 } … … 1421 1422 for (sp = psh->cmdenviron; sp; sp = sp->next) 1422 1423 setvareq(psh, sp->text, VEXPORT|VSTACK); 1423 shellexec(psh, argv + 1, environment(psh), pathval(psh), 0 );1424 shellexec(psh, argv + 1, environment(psh), pathval(psh), 0, -1); 1424 1425 } 1425 1426 return 0; -
trunk/src/kash/exec.c
r3438 r3475 46 46 #include <stdlib.h> 47 47 #include <stddef.h> 48 #include <assert.h> 48 49 49 50 /* … … 98 99 //STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */ 99 100 //int exerrno = 0; /* Last exec error */ 101 #ifdef PC_EXE_EXTS 102 STATIC const char * const g_exe_suffixes[] = { "", ".exe", ".cmd", ".btm", ".com" }; 103 #endif 100 104 101 105 … … 107 111 STATIC void delete_cmd_entry(shinstance *); 108 112 #ifdef PC_EXE_EXTS 109 STATIC int stat_pc_exec_exts(shinstance *, char *fullname, struct stat *st, int has_ext);113 STATIC int stat_pc_exec_exts(shinstance *, char *fullname, int has_ext, int *suffixp); 110 114 #endif 111 115 … … 136 140 case CMDUNKNOWN: 137 141 case CMDNORMAL: 138 dst->param.index = csrc->param.index; 142 dst->param.n.index = csrc->param.n.index; 143 dst->param.n.suffix = csrc->param.n.suffix; 139 144 break; 140 145 case CMDFUNCTION: … … 162 167 163 168 /* 169 * Check if 'path' is an absolute (starts with root) path or not. 170 */ 171 K_INLINE isabspath(const char *path) 172 { 173 #if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2 174 if (path[0] == '/' || path[0] == '\\') { 175 if ( (path[1] == '/' || path[1] == '\\') 176 && (path[2] != '/' && path[2] != '\\' && path[2])) 177 return 1; 178 } else if (path[0] && path[1] == ':' && (path[2] == '\\' || path[2] == '/') && isalpha(path[0])) { 179 return 1; 180 } 181 return 0; 182 #else 183 return path[0] == '/'; 184 #endif 185 } 186 187 /* 188 * Checks if the filename include a path or not. 189 */ 190 K_INLINE haspath(const char *name) 191 { 192 #if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2 193 return strchr(name, '/') != NULL 194 || strchr(name, '\\') != NULL 195 || (name[0] && name[1] == ':'); 196 #else 197 return strchr(name, '/') != NULL; 198 #endif 199 } 200 201 202 /* 164 203 * Exec a program. Never returns. If you change this routine, you may 165 204 * have to change the find_command routine as well. … … 167 206 168 207 SH_NORETURN_1 void 169 shellexec(shinstance *psh, char **argv, char **envp, const char *path, int idx )208 shellexec(shinstance *psh, char **argv, char **envp, const char *path, int idx, int suffix) 170 209 { 171 210 char *cmdname; … … 189 228 const int has_ext = 1; 190 229 #endif 191 TRACE((psh, "shellexec: argv[0]=%s idx=%d\n", argv0, idx)); 192 if (strchr(argv0, '/') != NULL) { 193 cmdname = stalloc(psh, argv0len + 5); 194 strcpy(cmdname, argv0); 230 TRACE((psh, "shellexec: argv[0]=%s idx=%d suffix=%d\n", argv0, idx, suffix)); 231 if (haspath(argv0)) { 232 #ifdef PC_EXE_EXTS 233 if (!has_ext && suffix && (unsigned)suffix < K_ELEMENTS(g_exe_suffixes)) { 234 size_t sufflen = strlen(g_exe_suffixes[suffix]); 235 cmdname = stalloc(psh, argv0len + sufflen + 1); 236 memcpy(cmdname, argv0, argv0len); 237 memcpy(cmdname + argv0len, g_exe_suffixes[suffix], sufflen + 1); 238 } else 239 #endif 240 { 241 cmdname = stalloc(psh, argv0len + 5); 242 memcpy(cmdname, argv0, argv0len + 1); 243 } 195 244 tryexec(psh, cmdname, argv, envp, has_ext); 196 245 TRACE((psh, "shellexec: cmdname=%s\n", cmdname)); … … 214 263 while ((cmdname = padvance(psh, &path, argv0)) != NULL) { 215 264 if (--idx < 0 && psh->pathopt == NULL) { 265 #ifdef PC_EXE_EXTS 266 if (!has_ext && idx == -1 && suffix && (unsigned)suffix < K_ELEMENTS(g_exe_suffixes)) 267 strcat(cmdname, g_exe_suffixes[suffix]); 268 #endif 216 269 tryexec(psh, cmdname, argv, envp, has_ext); 217 270 if (errno != ENOENT && errno != ENOTDIR) … … 250 303 #ifdef PC_EXE_EXTS 251 304 /* exploit the effect of stat_pc_exec_exts which adds the 252 * correct extentions to the file. 253 */ 254 struct stat st; 255 if (!has_ext) 256 stat_pc_exec_exts(psh, cmd, &st, 0); 305 * correct extentions to the file. */ 306 if (!has_ext) { 307 int suffix; 308 int isreg = stat_pc_exec_exts(psh, cmd, 0, &suffix); 309 assert(isreg > 0); 310 } 257 311 #endif 258 312 #if defined(__INNOTEK_LIBC__) && defined(EXEC_HASH_BANG_SCRIPT) … … 396 450 /* nothing*/; 397 451 TRACE((psh, "hash bang '%s'\n", new[0])); 398 shellexec(psh, new, envp, pathval(psh), 0 );452 shellexec(psh, new, envp, pathval(psh), 0, -1); 399 453 /* NOTREACHED */ 400 454 } … … 466 520 467 521 #ifdef PC_EXE_EXTS 468 STATIC int stat_pc_exec_exts(shinstance *psh, char *fullname, struct stat *st, int has_ext) 469 { 522 STATIC int stat_pc_exec_exts(shinstance *psh, char *fullname, int has_ext, int *suffixp) 523 { 524 int isreg; 525 470 526 /* skip the SYSV crap */ 471 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 472 return 0; 527 if ((isreg = shfile_stat_isreg(&psh->fdtab, fullname)) >= 1) { 528 *suffixp = 0; 529 return isreg; 530 } 473 531 if (!has_ext && errno == ENOENT) 474 532 { 533 /* Ignore non-regular files here. */ 475 534 char *psz = strchr(fullname, '\0'); 476 memcpy(psz, ".exe", 5); 477 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 478 return 0; 479 if (errno != ENOENT && errno != ENOTDIR) 480 return -1; 481 482 memcpy(psz, ".cmd", 5); 483 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 484 return 0; 485 if (errno != ENOENT && errno != ENOTDIR) 486 return -1; 487 488 memcpy(psz, ".bat", 5); 489 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 490 return 0; 491 if (errno != ENOENT && errno != ENOTDIR) 492 return -1; 493 494 memcpy(psz, ".com", 5); 495 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 496 return 0; 497 if (errno != ENOENT && errno != ENOTDIR) 498 return -1; 499 500 memcpy(psz, ".btm", 5); 501 if (shfile_stat(&psh->fdtab, fullname, st) >= 0) 502 return 0; 503 *psz = '\0'; 535 int i; 536 for (i = 1 /*first entry is empty*/; i < K_ELEMENTS(g_exe_suffixes); i++) { 537 strcpy(psz, g_exe_suffixes[i]); 538 if ((isreg = shfile_stat_isreg(&psh->fdtab, fullname)) >= 1) { 539 *suffixp = i; 540 return isreg; 541 } 542 if (isreg < 0 && errno != ENOENT && errno != ENOTDIR) 543 break; 544 } 504 545 } 505 return -1; 546 *suffixp = -1; 547 return isreg; 506 548 } 507 549 #endif /* PC_EXE_EXTS */ … … 567 609 switch (cmdp->cmdtype) { 568 610 case CMDNORMAL: 569 idx = cmdp->param. index;611 idx = cmdp->param.n.index; 570 612 path = pathval(psh); 571 613 do { … … 574 616 } while (--idx >= 0); 575 617 out1str(psh, name); 618 #ifdef PC_EXE_EXTS 619 if ((unsigned)cmdp->param.n.suffix < K_ELEMENTS(g_exe_suffixes)) 620 out1str(psh, g_exe_suffixes[cmdp->param.n.suffix]); 621 #endif 576 622 break; 577 623 case CMDSPLBLTIN: … … 614 660 int idx; 615 661 int prev; 662 int norehashoncd = 1; 616 663 char *fullname; 617 struct stat statb;618 664 int e; 619 665 int (*bltin)(shinstance*,int,char **); … … 635 681 636 682 /* If name contains a slash, don't use PATH or hash table */ 637 if ( strchr(name, '/') != NULL) {683 if (haspath(name)) { 638 684 if (act & DO_ABS) { 639 while (shfile_stat (&psh->fdtab, name, &statb) < 0) {685 while (shfile_stat_exists(&psh->fdtab, name) < 0) { 640 686 #ifdef SYSV 641 687 if (errno == EINTR) … … 645 691 e = errno; 646 692 entry->cmdtype = CMDUNKNOWN; 647 entry->u.index = -1; 693 entry->u.n.index = -1; 694 entry->u.n.suffix = -1; 648 695 return; 649 696 } 650 697 entry->cmdtype = CMDNORMAL; 651 entry->u.index = -1; 698 entry->u.n.index = -1; 699 entry->u.n.suffix = -1; 652 700 return; 653 701 } 654 702 entry->cmdtype = CMDNORMAL; 655 entry->u.index = 0; 703 entry->u.n.index = 0; 704 entry->u.n.suffix = 0; 656 705 return; 657 706 } … … 703 752 prev = psh->builtinloc; 704 753 else 705 prev = cmdp->param. index;754 prev = cmdp->param.n.index; 706 755 } 707 756 … … 723 772 loop: 724 773 while ((fullname = padvance(psh, &path, name)) != NULL) { 774 #ifdef PC_EXE_EXTS 775 int suffix; 776 #endif 777 int isreg; 725 778 stunalloc(psh, fullname); 726 779 idx++; … … 738 791 } 739 792 /* if rehash, don't redo absolute path names */ 740 if ( fullname[0] == '/' && idx <= prev) {793 if (idx <= prev && isabspath(fullname)) { 741 794 if (idx < prev) 742 795 goto loop; … … 745 798 } 746 799 #ifdef PC_EXE_EXTS 747 while ( stat_pc_exec_exts(psh, fullname, &statb, has_ext) < 0) {800 while ((isreg = stat_pc_exec_exts(psh, fullname, has_ext, &suffix)) < 0) { 748 801 #else 749 while ( shfile_stat(&psh->fdtab, fullname, &statb) < 0) {802 while ((isreg = shfile_stat_isreg(&psh->fdtab, fullname)) < 0) { 750 803 #endif 751 804 #ifdef SYSV … … 759 812 } 760 813 e = EACCES; /* if we fail, this will be the error */ 761 if ( !S_ISREG(statb.st_mode))814 if (isreg < 1) 762 815 goto loop; 763 816 if (psh->pathopt) { /* this is a %func directory */ … … 794 847 cmdp = cmdlookup(psh, name, 1); 795 848 cmdp->cmdtype = CMDNORMAL; 796 cmdp->param.index = idx; 849 cmdp->param.n.index = idx; 850 cmdp->param.n.suffix = suffix; 797 851 INTON; 798 852 goto success; … … 971 1025 while ((cmdp = *pp) != NULL) { 972 1026 if ((cmdp->cmdtype == CMDNORMAL && 973 cmdp->param. index >= firstchange)1027 cmdp->param.n.index >= firstchange) 974 1028 || (cmdp->cmdtype == CMDBUILTIN && 975 1029 psh->builtinloc >= firstchange)) { … … 1064 1118 cmdp->cmdtype = CMDUNKNOWN; 1065 1119 cmdp->rehash = 0; 1120 cmdp->param.n.index = 0; 1121 cmdp->param.n.suffix = 0; 1066 1122 strcpy(cmdp->cmdname, name); 1067 1123 INTON; … … 1229 1285 switch (entry.cmdtype) { 1230 1286 case CMDNORMAL: { 1231 if ( strchr(arg, '/') == NULL) {1287 if (!haspath(arg)) { 1232 1288 const char *path = pathval(psh); 1233 1289 char *name; 1234 int j = entry.u. index;1290 int j = entry.u.n.index; 1235 1291 do { 1236 1292 name = padvance(psh, &path, arg); … … 1240 1296 out1fmt(psh, " is%s ", 1241 1297 cmdp ? " a tracked alias for" : ""); 1242 out1fmt(psh, "%s\n", name); 1298 #ifdef PC_EXE_EXTS 1299 if ((unsigned)entry.u.n.suffix < K_ELEMENTS(g_exe_suffixes)) 1300 out1fmt(psh, "%s%s\n", name, g_exe_suffixes[entry.u.n.suffix]); 1301 else 1302 #endif 1303 out1fmt(psh, "%s\n", name); 1243 1304 } else { 1244 1305 if (shfile_access(&psh->fdtab, arg, X_OK) == 0) { -
trunk/src/kash/exec.h
r3438 r3475 47 47 48 48 union param { 49 int index; 49 struct 50 { 51 int index; 52 int suffix; /* PC suffix index */ 53 } n; 50 54 int (*bltin)(struct shinstance*, int, char**); 51 55 union node *func; … … 74 78 void subshellinitexec(shinstance *, shinstance *); 75 79 #endif 76 SH_NORETURN_1 void shellexec(struct shinstance *, char **, char **, const char *, int ) SH_NORETURN_2;80 SH_NORETURN_1 void shellexec(struct shinstance *, char **, char **, const char *, int, int) SH_NORETURN_2; 77 81 char *padvance(struct shinstance *, const char **, const char *); 78 82 int hashcmd(struct shinstance *, int, char **);
Note:
See TracChangeset
for help on using the changeset viewer.