- Timestamp:
- Mar 1, 2009 7:25:29 AM (16 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/shfile.c
r2302 r2303 73 73 return (rc); \ 74 74 } while (0) 75 76 #if K_OS == K_OS_WINDOWS 77 /* See msdos.h for description. */ 78 # define FOPEN 0x01 79 # define FEOFLAG 0x02 80 # define FCRLF 0x04 81 # define FPIPE 0x08 82 # define FNOINHERIT 0x10 83 # define FAPPEND 0x20 84 # define FDEV 0x40 85 # define FTEXT 0x80 86 #endif 75 87 76 88 … … 448 460 } 449 461 450 #if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE) //&& defined(SH_FORKED_MODE) 462 #if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE) 463 451 464 /** 452 465 * Helper for shfork. … … 461 474 shmtxtmp tmp; 462 475 unsigned i; 476 DWORD fFlag = set ? HANDLE_FLAG_INHERIT : 0; 463 477 464 478 shmtx_enter(&pfdtab->mtx, &tmp); … … 471 485 { 472 486 HANDLE hFile = (HANDLE)pfdtab->tab[i].native; 473 DWORD fFlag = (set || !pfdtab->tab[i].cloexec)474 ? HANDLE_FLAG_INHERIT : 0;475 487 if (set) 476 TRACE2((NULL, " #%d: native=%#x flags=%#x cloexec=%d fFlag=%#x\n", 477 i, pfdtab->tab[i].flags, hFile, pfdtab->tab[i].cloexec, fFlag)); 478 488 TRACE2((NULL, " #%d: native=%#x flags=%#x cloexec=%d\n", 489 i, pfdtab->tab[i].flags, hFile, pfdtab->tab[i].cloexec)); 479 490 if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, fFlag)) 480 491 { … … 499 510 shmtx_leave(&pfdtab->mtx, &tmp); 500 511 } 501 #endif 512 513 /** 514 * Helper for sh_execve. 515 * 516 * This is called before and after CreateProcess. On the first call it 517 * will mark the non-close-on-exec handles as inheritable and produce 518 * the startup info for the CRT. On the second call, after CreateProcess, 519 * it will restore the handle inheritability properties. 520 * 521 * @returns Pointer to CRT data if prepare is 1, NULL if prepare is 0. 522 * @param pfdtab The file descriptor table. 523 * @param prepare Which call, 1 if before and 0 if after. 524 * @param sizep Where to store the size of the returned data. 525 * @param hndls Where to store the three standard handles. 526 */ 527 void *shfile_exec_win(shfdtab *pfdtab, int prepare, unsigned short *sizep, intptr_t *hndls) 528 { 529 void *pvRet; 530 shmtxtmp tmp; 531 unsigned count; 532 unsigned i; 533 534 shmtx_enter(&pfdtab->mtx, &tmp); 535 TRACE2((NULL, "shfile_fork_win:\n")); 536 537 count = pfdtab->size < (0x10000-4) / (1 + sizeof(HANDLE)) 538 ? pfdtab->size 539 : (0x10000-4) / (1 + sizeof(HANDLE)); 540 541 if (prepare) 542 { 543 size_t cbData = sizeof(int) + count * (1 + sizeof(HANDLE)); 544 uint8_t *pbData = sh_malloc(shthread_get_shell(), cbData); 545 uint8_t *paf = pbData + sizeof(int); 546 HANDLE *pah = (HANDLE *)(paf + count); 547 548 *(int *)pbData = count; 549 550 i = count; 551 while (i-- > 0) 552 { 553 if ( pfdtab->tab[i].fd == i 554 && !pfdtab->tab[i].cloexec) 555 { 556 HANDLE hFile = (HANDLE)pfdtab->tab[i].native; 557 TRACE2((NULL, " #%d: native=%#x flags=%#x\n", 558 i, pfdtab->tab[i].flags, hFile)); 559 560 if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) 561 { 562 DWORD err = GetLastError(); 563 assert(0); 564 } 565 paf[i] = FOPEN; 566 if (pfdtab->tab[i].flags & _O_APPEND) 567 paf[i] = FAPPEND; 568 if (pfdtab->tab[i].flags & _O_TEXT) 569 paf[i] = FTEXT; 570 pah[i] = hFile; 571 } 572 else 573 { 574 paf[i] = 0; 575 pah[i] = INVALID_HANDLE_VALUE; 576 } 577 } 578 579 for (i = 0; i < 3; i++) 580 { 581 if ( count > i 582 && pfdtab->tab[i].fd == 0) 583 hndls[i] = pfdtab->tab[i].native; 584 else 585 hndls[i] = (intptr_t)INVALID_HANDLE_VALUE; 586 } 587 588 *sizep = (unsigned short)cbData; 589 pvRet = pbData; 590 } 591 else 592 { 593 assert(!hndls); 594 assert(!sizep); 595 i = count; 596 while (i-- > 0) 597 { 598 if ( pfdtab->tab[i].fd == i 599 && !pfdtab->tab[i].cloexec) 600 { 601 HANDLE hFile = (HANDLE)pfdtab->tab[i].native; 602 if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, 0)) 603 { 604 DWORD err = GetLastError(); 605 assert(0); 606 } 607 } 608 } 609 pvRet = NULL; 610 } 611 612 shmtx_leave(&pfdtab->mtx, &tmp); 613 return pvRet; 614 } 615 616 #endif /* K_OS_WINDOWS */ 502 617 503 618 … … 538 653 SecurityAttributes.nLength = sizeof(SecurityAttributes); 539 654 SecurityAttributes.lpSecurityDescriptor = NULL; 540 SecurityAttributes.bInheritHandle = (flags & _O_NOINHERIT) == 0;655 SecurityAttributes.bInheritHandle = FALSE; 541 656 542 657 if (flags & _O_CREAT) … … 599 714 # endif /* K_OS != K_OS_WINDOWS */ 600 715 601 #el if defined(SH_FORKED_MODE)716 #else 602 717 fd = open(name, flags, mode); 603 718 #endif … … 619 734 SecurityAttributes.nLength = sizeof(SecurityAttributes); 620 735 SecurityAttributes.lpSecurityDescriptor = NULL; 621 SecurityAttributes.bInheritHandle = TRUE;736 SecurityAttributes.bInheritHandle = FALSE; 622 737 623 738 fds[1] = fds[0] = -1; … … 680 795 } 681 796 682 #el if defined(SH_FORKED_MODE)797 #else 683 798 rc = pipe(fds); 684 799 #endif … … 688 803 } 689 804 805 /** 806 * dup(). 807 */ 690 808 int shfile_dup(shfdtab *pfdtab, int fd) 691 809 { 692 int rc; 693 #if defined(SH_FORKED_MODE) 694 rc = dup(fd); 695 696 #else 697 #endif 698 699 TRACE2((NULL, "shfile_dup(%d) -> %d [%d]\n", fd, rc, errno)); 700 return rc; 810 return shfile_fcntl(pfdtab,fd, F_DUPFD, 0); 701 811 } 702 812 … … 724 834 rc = -1; 725 835 726 #el if defined(SH_FORKED_MODE)836 #else 727 837 rc = close(fd); 728 838 #endif … … 758 868 rc = -1; 759 869 760 #el if defined(SH_FORKED_MODE)870 #else 761 871 rc = read(fd, buf, len); 762 872 #endif … … 790 900 rc = -1; 791 901 792 #el if defined(SH_FORKED_MODE)902 #else 793 903 rc = write(fd, buf, len); 794 904 #endif … … 823 933 rc = -1; 824 934 825 #el if defined(SH_FORKED_MODE)935 #else 826 936 rc = lseek(fd, off, whench); 827 937 #endif … … 882 992 &hNew, 883 993 0, 884 TRUE /* bInheritHandle */,994 FALSE /* bInheritHandle */, 885 995 DUPLICATE_SAME_ACCESS)) 886 996 rc = shfile_insert(pfdtab, (intptr_t)hNew, file->flags, arg, "shfile_fcntl"); … … 906 1016 rc = -1; 907 1017 908 #el if defined(SH_FORKED_MODE)1018 #else 909 1019 rc = fcntl(fd, cmd, arg); 910 1020 #endif … … 922 1032 int shfile_stat(shfdtab *pfdtab, const char *path, struct stat *pst) 923 1033 { 924 #if defined(SH_FORKED_MODE) 1034 #ifdef SHFILE_IN_USE 1035 char abspath[SHFILE_MAX_PATH]; 1036 int rc; 1037 rc = shfile_make_path(pfdtab, path, &abspath[0]); 1038 if (!rc) 1039 { 1040 # if K_OS == K_OS_WINDOWS 1041 rc = stat(abspath, pst); /** @todo re-implement stat. */ 1042 # else 1043 rc = stat(abspath, pst); 1044 # endif 1045 } 1046 TRACE2((NULL, "shfile_stat(,%s,) -> %d [%d]\n", path, rc, errno)); 1047 return rc; 1048 #else 925 1049 return stat(path, pst); 926 927 #else 928 #endif 929 } 930 931 int shfile_lstat(shfdtab *pfdtab, const char *link, struct stat *pst) 932 { 933 #if defined(SH_FORKED_MODE) 934 # ifdef _MSC_VER 935 return stat(link, pst); 1050 #endif 1051 } 1052 1053 int shfile_lstat(shfdtab *pfdtab, const char *path, struct stat *pst) 1054 { 1055 int rc; 1056 #ifdef SHFILE_IN_USE 1057 char abspath[SHFILE_MAX_PATH]; 1058 1059 rc = shfile_make_path(pfdtab, path, &abspath[0]); 1060 if (!rc) 1061 { 1062 # if K_OS == K_OS_WINDOWS 1063 rc = stat(abspath, pst); /** @todo implement lstat. */ 936 1064 # else 937 return lstat(link, pst); 938 # endif 939 940 #else 941 #endif 942 } 943 1065 rc = lstat(abspath, pst); 1066 # endif 1067 } 1068 #else 1069 rc = stat(path, pst); 1070 #endif 1071 TRACE2((NULL, "shfile_stat(,%s,) -> %d [%d]\n", path, rc, errno)); 1072 return rc; 1073 } 1074 1075 /** 1076 * chdir(). 1077 */ 944 1078 int shfile_chdir(shfdtab *pfdtab, const char *path) 945 1079 { 946 #if defined(SH_FORKED_MODE) 947 # ifdef _MSC_VER //??? 948 return chdir(path); 949 # else 950 return chdir(path); 951 # endif 952 953 #else 954 #endif 955 } 956 957 char *shfile_getcwd(shfdtab *pfdtab, char *buf, int len) 958 { 959 #if defined(SH_FORKED_MODE) 960 return getcwd(buf, len); 961 962 #else 963 #endif 1080 shinstance *psh = shthread_get_shell(); 1081 int rc; 1082 #ifdef SHFILE_IN_USE 1083 char abspath[SHFILE_MAX_PATH]; 1084 1085 rc = shfile_make_path(pfdtab, path, &abspath[0]); 1086 if (!rc) 1087 { 1088 char *abspath_copy = sh_strdup(psh, abspath); 1089 char *free_me = abspath_copy; 1090 rc = chdir(path); 1091 if (!rc) 1092 { 1093 shmtxtmp tmp; 1094 shmtx_enter(&pfdtab->mtx, &tmp); 1095 1096 free_me = pfdtab->cwd; 1097 pfdtab->cwd = abspath_copy; 1098 1099 shmtx_leave(&pfdtab->mtx, &tmp); 1100 } 1101 sh_free(psh, free_me); 1102 } 1103 #else 1104 rc = chdir(path); 1105 #endif 1106 1107 TRACE2((psh, "shfile_chdir(,%s) -> %d [%d]\n", path, rc, errno)); 1108 return rc; 1109 } 1110 1111 /** 1112 * getcwd(). 1113 */ 1114 char *shfile_getcwd(shfdtab *pfdtab, char *buf, int size) 1115 { 1116 char *ret; 1117 #ifdef SHFILE_IN_USE 1118 1119 ret = NULL; 1120 if (buf && !size) 1121 errno = -EINVAL; 1122 else 1123 { 1124 size_t cwd_size; 1125 shmtxtmp tmp; 1126 shmtx_enter(&pfdtab->mtx, &tmp); 1127 1128 cwd_size = strlen(pfdtab->cwd) + 1; 1129 if (buf) 1130 { 1131 if (cwd_size <= (size_t)size) 1132 ret = memcpy(buf, pfdtab->cwd, cwd_size); 1133 else 1134 errno = ERANGE; 1135 } 1136 else 1137 { 1138 if (size < cwd_size) 1139 size = (int)cwd_size; 1140 ret = sh_malloc(shthread_get_shell(), size); 1141 if (ret) 1142 ret = memcpy(ret, pfdtab->cwd, cwd_size); 1143 else 1144 errno = ENOMEM; 1145 } 1146 1147 shmtx_leave(&pfdtab->mtx, &tmp); 1148 } 1149 #else 1150 ret = getcwd(buf, size); 1151 #endif 1152 1153 TRACE2((NULL, "shfile_getcwd(,%p,%d) -> %s [%d]\n", buf, size, ret, errno)); 1154 return ret; 964 1155 } 965 1156 966 1157 int shfile_access(shfdtab *pfdtab, const char *path, int type) 967 1158 { 968 #if defined(SH_FORKED_MODE)969 1159 # ifdef _MSC_VER 970 1160 type &= ~X_OK; … … 973 1163 return access(path, type); 974 1164 # endif 975 976 #else 977 #endif 978 } 979 1165 } 1166 1167 /** 1168 * isatty() 1169 */ 980 1170 int shfile_isatty(shfdtab *pfdtab, int fd) 981 1171 { 982 int rc; 983 984 #if defined(SH_FORKED_MODE) 1172 int rc; 1173 #ifdef SHFILE_IN_USE 1174 shmtxtmp tmp; 1175 shfile *file = shfile_get(pfdtab, fd, &tmp); 1176 if (file) 1177 { 1178 # if K_OS == K_OS_WINDOWS 1179 errno = ENOSYS; 1180 # else 1181 rc = isatty(file->native); 1182 # endif 1183 shfile_put(pfdtab, file, &tmp); 1184 } 1185 else 1186 rc = 0; 1187 #else 985 1188 rc = isatty(fd); 986 #else987 1189 #endif 988 1190 … … 991 1193 } 992 1194 993 1195 /** 1196 * fcntl F_SETFD / FD_CLOEXEC. 1197 */ 994 1198 int shfile_cloexec(shfdtab *pfdtab, int fd, int closeit) 995 1199 { 996 int rc; 997 998 #if defined(SH_FORKED_MODE) 999 # ifdef _MSC_VER 1000 errno = ENOSYS; 1001 rc = -1; 1002 # else 1200 int rc; 1201 #ifdef SHFILE_IN_USE 1202 shmtxtmp tmp; 1203 shfile *file = shfile_get(pfdtab, fd, &tmp); 1204 if (file) 1205 { 1206 file->cloexec = !!(closeit); 1207 shfile_put(pfdtab, file, &tmp); 1208 } 1209 else 1210 rc = -1; 1211 #else 1003 1212 rc = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) 1004 1213 | (closeit ? FD_CLOEXEC : 0)); 1005 # endif1006 1007 #else1008 1214 #endif 1009 1215 … … 1015 1221 int shfile_ioctl(shfdtab *pfdtab, int fd, unsigned long request, void *buf) 1016 1222 { 1017 int rc; 1018 1019 #if defined(SH_FORKED_MODE) 1020 # ifdef _MSC_VER 1021 errno = ENOSYS; 1022 rc = -1; 1223 int rc; 1224 #ifdef SHFILE_IN_USE 1225 shmtxtmp tmp; 1226 shfile *file = shfile_get(pfdtab, fd, &tmp); 1227 if (file) 1228 { 1229 # if K_OS == K_OS_WINDOWS 1230 rc = -1; 1231 errno = ENOSYS; 1023 1232 # else 1233 rc = ioctl(file->native, request, buf); 1234 # endif 1235 shfile_put(pfdtab, file, &tmp); 1236 } 1237 else 1238 rc = -1; 1239 #else 1024 1240 rc = ioctl(fd, request, buf); 1025 # endif1026 1027 #else1028 1241 #endif 1029 1242 … … 1035 1248 mode_t shfile_get_umask(shfdtab *pfdtab) 1036 1249 { 1037 #if defined(SH_FORKED_MODE) 1250 /** @todo */ 1038 1251 return 022; 1039 1040 #else1041 #endif1042 1252 } 1043 1253 1044 1254 void shfile_set_umask(shfdtab *pfdtab, mode_t mask) 1045 1255 { 1256 /** @todo */ 1046 1257 (void)mask; 1047 1258 } … … 1050 1261 shdir *shfile_opendir(shfdtab *pfdtab, const char *dir) 1051 1262 { 1052 #if defined(SH_FORKED_MODE) 1053 # ifdef _MSC_VER 1263 #ifdef SHFILE_IN_USE 1054 1264 errno = ENOSYS; 1055 1265 return NULL; 1056 # 1266 #else 1057 1267 return (shdir *)opendir(dir); 1058 # endif1059 1060 #else1061 1268 #endif 1062 1269 } … … 1064 1271 shdirent *shfile_readdir(struct shdir *pdir) 1065 1272 { 1066 #if defined(SH_FORKED_MODE) 1067 # ifdef _MSC_VER 1273 #ifdef SHFILE_IN_USE 1068 1274 errno = ENOSYS; 1069 1275 return NULL; 1070 # 1276 #else 1071 1277 struct dirent *pde = readdir((DIR *)pdir); 1072 1278 return pde ? (shdirent *)&pde->d_name[0] : NULL; 1073 # endif1074 1075 #else1076 1279 #endif 1077 1280 } … … 1079 1282 void shfile_closedir(struct shdir *pdir) 1080 1283 { 1081 #if defined(SH_FORKED_MODE) 1082 # ifdef _MSC_VER 1284 #ifdef SHFILE_IN_USE 1083 1285 errno = ENOSYS; 1084 # 1286 #else 1085 1287 closedir((DIR *)pdir); 1086 # endif 1087 1088 #else 1089 #endif 1090 } 1288 #endif 1289 } 1290 -
trunk/src/kash/shfile.h
r2293 r2303 103 103 int fd; /**< The shell file descriptor number. */ 104 104 int flags; /**< Open flags. */ 105 intcloexec : 1; /**< Close on exec flag. */105 unsigned cloexec : 1; /**< Close on exec flag. */ 106 106 intptr_t native; /**< The native file descriptor number. */ 107 107 } shfile; … … 120 120 int shfile_init(shfdtab *, shfdtab *); 121 121 void shfile_fork_win(shfdtab *pfdtab, int set, intptr_t *hndls); 122 void *shfile_exec_win(shfdtab *pfdtab, int prepare, unsigned short *sizep, intptr_t *hndls); 122 123 123 124 int shfile_open(shfdtab *, const char *, unsigned, mode_t); -
trunk/src/kash/shinstance.c
r2302 r2303 1055 1055 int sh_execve(shinstance *psh, const char *exe, const char * const *argv, const char * const *envp) 1056 1056 { 1057 #ifdef _MSC_VER1058 intptr_t rc;1059 #else1060 1057 int rc; 1061 #endif1062 1058 1063 1059 #ifdef DEBUG … … 1071 1067 envp = sh_environ(psh); 1072 1068 1073 #if defined(SH_FORKED_MODE) 1069 #if defined(SH_FORKED_MODE) && K_OS != K_OS_WINDOWS 1070 # ifdef _MSC_VER 1074 1071 errno = 0; 1075 # ifdef _MSC_VER 1076 errno = 0; 1077 rc = _spawnve(_P_WAIT, exe, (char **)argv, (char **)envp); 1078 if (rc != -1) 1079 { 1080 TRACE2((psh, "sh_execve: child exited, rc=%d. (errno=%d)\n", rc, errno)); 1081 exit((int)rc); 1082 } 1072 { 1073 intptr_t rc2 = _spawnve(_P_WAIT, exe, (char **)argv, (char **)envp); 1074 if (rc2 != -1) 1075 { 1076 TRACE2((psh, "sh_execve: child exited, rc=%d. (errno=%d)\n", rc, errno)); 1077 rc = (int)rc2; 1078 if (!rc && rc2) 1079 rc = 16; 1080 exit(rc); 1081 } 1082 } 1083 rc = -1; 1083 1084 # else 1084 1085 rc = execve(exe, (char **)argv, (char **)envp); … … 1086 1087 1087 1088 #else 1089 # if K_OS == K_OS_WINDOWS 1090 { 1091 /* 1092 * This ain't quite straight forward on Windows... 1093 */ 1094 PROCESS_INFORMATION ProcInfo; 1095 STARTUPINFO StrtInfo; 1096 intptr_t hndls[3]; 1097 char *cwd = shfile_getcwd(&psh->fdtab, NULL, 0); 1098 char *cmdline; 1099 size_t cmdline_size; 1100 char *envblock; 1101 size_t env_size; 1102 char *p; 1103 int i; 1104 1105 /* Create the environment block. */ 1106 if (!envp) 1107 envp = sh_environ(psh); 1108 env_size = 2; 1109 for (i = 0; envp[i]; i++) 1110 env_size += strlen(envp[i]) + 1; 1111 envblock = p = sh_malloc(psh, env_size); 1112 for (i = 0; envp[i]; i++) 1113 { 1114 size_t len = strlen(envp[i]) + 1; 1115 memcpy(p, envp[i], len); 1116 p += len; 1117 } 1118 *p = '\0'; 1119 1120 /* Create the command line. */ 1121 cmdline_size = 2; 1122 for (i = 0; argv[i]; i++) 1123 cmdline_size += strlen(argv[i]) + 3; 1124 cmdline = p = sh_malloc(psh, env_size); 1125 for (i = 0; argv[i]; i++) 1126 { 1127 size_t len = strlen(argv[i]); 1128 int quoted = !!strpbrk(argv[i], " \t"); /** @todo Do this quoting business right. */ 1129 if (i != 0) 1130 *(p++) = ' '; 1131 if (quoted) 1132 *(p++) = '"'; 1133 memcpy(p, argv[i], len); 1134 p += len; 1135 if (quoted) 1136 *(p++) = '"'; 1137 } 1138 p[0] = p[1] = '\0'; 1139 1140 /* Init the info structure */ 1141 memset(&StrtInfo, '\0', sizeof(StrtInfo)); 1142 StrtInfo.cb = sizeof(StrtInfo); 1143 1144 /* File handles. */ 1145 StrtInfo.lpReserved2 = shfile_exec_win(&psh->fdtab, 1 /* prepare */, &StrtInfo.cbReserved2, hndls); 1146 StrtInfo.hStdInput = (HANDLE)hndls[0]; 1147 StrtInfo.hStdOutput = (HANDLE)hndls[1]; 1148 StrtInfo.hStdError = (HANDLE)hndls[2]; 1149 1150 /* Get going... */ 1151 if (CreateProcess(exe, 1152 cmdline, 1153 NULL, /* pProcessAttributes */ 1154 NULL, /* pThreadAttributes */ 1155 TRUE, /* bInheritHandles */ 1156 0, /* dwCreationFlags */ 1157 envblock, 1158 cwd, 1159 &StrtInfo, 1160 &ProcInfo)) 1161 { 1162 DWORD dwErr; 1163 DWORD dwExitCode; 1164 1165 CloseHandle(ProcInfo.hThread); 1166 dwErr = WaitForSingleObject(ProcInfo.hProcess, INFINITE); 1167 assert(dwErr == WAIT_OBJECT_0); 1168 1169 if (GetExitCodeProcess(ProcInfo.hProcess, &dwExitCode)) 1170 { 1171 CloseHandle(ProcInfo.hProcess); 1172 _exit(dwExitCode); 1173 } 1174 errno = EINVAL; 1175 } 1176 1177 shfile_exec_win(&psh->fdtab, 0 /* done */, NULL, NULL); 1178 } 1179 rc = -1; 1180 1181 # else 1182 errno = ENOSYS; 1183 rc = -1; 1184 # endif 1088 1185 #endif 1089 1186
Note:
See TracChangeset
for help on using the changeset viewer.