Changeset 2293 for trunk/src/kash/shinstance.c
- Timestamp:
- Feb 28, 2009, 8:25:12 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/shinstance.c
r2292 r2293 38 38 # include <pwd.h> 39 39 #endif 40 #if K_OS == K_OS_WINDOWS 41 # include <Windows.h> 42 #endif 40 43 #include "shinstance.h" 41 44 42 45 #if K_OS == K_OS_WINDOWS 43 extern pid_t shfork_do_it( void); /* shforkA-win.asm */46 extern pid_t shfork_do_it(shinstance *psh); /* shforkA-win.asm */ 44 47 #endif 45 48 … … 308 311 } 309 312 313 /** getenv() */ 310 314 char *sh_getenv(shinstance *psh, const char *var) 311 315 { … … 868 872 } 869 873 874 /** 875 * Adds a child to the shell 876 * 877 * @returns 0 on success, on failure -1 and errno set to ENOMEM. 878 * 879 * @param psh The shell instance. 880 * @param pid The child pid. 881 * @param hChild Windows child handle. 882 */ 883 int sh_add_child(shinstance *psh, pid_t pid, void *hChild) 884 { 885 /* get a free table entry. */ 886 int i = psh->num_children++; 887 if (!(i % 32)) 888 { 889 void *ptr = sh_realloc(psh, psh->children, sizeof(*psh->children) * (i + 32)); 890 if (!ptr) 891 { 892 psh->num_children--; 893 errno = ENOMEM; 894 return -1; 895 } 896 psh->children = ptr; 897 } 898 899 /* add it */ 900 psh->children[i].pid = pid; 901 #if K_OS == K_OS_WINDOWS 902 psh->children[i].hChild = hChild; 903 #endif 904 (void)hChild; 905 return 0; 906 } 907 870 908 pid_t sh_fork(shinstance *psh) 871 909 { … … 877 915 878 916 #elif K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE) 879 pid = shfork_do_it( );917 pid = shfork_do_it(psh); 880 918 881 919 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) … … 896 934 } 897 935 936 /** waitpid() */ 898 937 pid_t sh_waitpid(shinstance *psh, pid_t pid, int *statusp, int flags) 899 938 { 900 939 pid_t pidret; 901 940 #ifdef SH_PURE_STUB_MODE 902 941 *statusp = 0; 903 #ifdef SH_PURE_STUB_MODE904 942 pidret = -1; 905 943 906 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 944 #elif K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE) 945 DWORD dwRet; 946 HANDLE hChild = INVALID_HANDLE_VALUE; 947 int i; 948 949 *statusp = 0; 950 pidret = -1; 951 if (pid != -1) 952 { 953 /* 954 * A specific child, try look it up in the child process table 955 * and wait for it. 956 */ 957 for (i = 0; i < psh->num_children; i++) 958 if (psh->children[i].pid == pid) 959 break; 960 if (i < psh->num_children) 961 { 962 dwRet = WaitForSingleObject(psh->children[i].hChild, 963 flags & WNOHANG ? 0 : INFINITE); 964 if (dwRet == WAIT_OBJECT_0) 965 hChild = psh->children[i].hChild; 966 else if (dwRet == WAIT_TIMEOUT) 967 { 968 i = -1; /* don't try close anything */ 969 pidret = 0; 970 } 971 else 972 errno = ECHILD; 973 } 974 else 975 errno = ECHILD; 976 } 977 else if (psh->num_children <= MAXIMUM_WAIT_OBJECTS) 978 { 979 HANDLE ahChildren[64]; 980 for (i = 0; i < psh->num_children; i++) 981 ahChildren[i] = psh->children[i].hChild; 982 dwRet = WaitForMultipleObjects(psh->num_children, &ahChildren[0], 983 FALSE, 984 flags & WNOHANG ? 0 : INFINITE); 985 i = dwRet - WAIT_OBJECT_0; 986 if ((unsigned)i < (unsigned)psh->num_children) 987 { 988 hChild = psh->children[i].hChild; 989 } 990 else if (dwRet == WAIT_TIMEOUT) 991 { 992 i = -1; /* don't try close anything */ 993 pidret = 0; 994 } 995 else 996 { 997 i = -1; /* don't try close anything */ 998 errno = EINVAL; 999 } 1000 } 1001 else 1002 { 1003 fprintf(stderr, "panic! too many children!\n"); 1004 i = -1; 1005 *(char *)1 = '\0'; /** @todo implement this! */ 1006 } 1007 1008 /* 1009 * Close the handle, and if we succeeded collect the exit code first. 1010 */ 1011 if ( i >= 0 1012 && i < psh->num_children) 1013 { 1014 if (hChild != INVALID_HANDLE_VALUE) 1015 { 1016 DWORD dwExitCode = 127; 1017 if (GetExitCodeProcess(hChild, &dwExitCode)) 1018 { 1019 pidret = psh->children[i].pid; 1020 if (dwExitCode && !W_EXITCODE(dwExitCode, 0)) 1021 dwExitCode |= 16; 1022 *statusp = W_EXITCODE(dwExitCode, 0); 1023 } 1024 else 1025 errno = EINVAL; 1026 } 1027 1028 /* remove and close */ 1029 hChild = psh->children[i].hChild; 1030 psh->num_children--; 1031 if (i < psh->num_children) 1032 psh->children[i] = psh->children[psh->num_children]; 1033 i = CloseHandle(hChild); assert(i); 1034 } 1035 1036 #elif defined(SH_STUB_MODE) || defined(SH_FORKED_MODE) 1037 *statusp = 0; 907 1038 # ifdef _MSC_VER 908 1039 pidret = -1;
Note:
See TracChangeset
for help on using the changeset viewer.