Changeset 3447 for trunk/src/kash/shinstance.c
- Timestamp:
- Sep 11, 2020, 3:22:14 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/shinstance.c
r3446 r3447 50 50 #if K_OS == K_OS_WINDOWS 51 51 # include <Windows.h> 52 # include "nt/nt_child_inject_standard_handles.h" 52 53 # ifdef SH_FORKED_MODE 53 54 extern pid_t shfork_do(shinstance *psh); /* shforkA-win.asm */ … … 70 71 #ifndef SH_FORKED_MODE 71 72 /** Mutex serializing exec/spawn to prevent unwanted file inherting. */ 72 s tatic shmtx g_sh_exec_mtx;73 shmtx g_sh_exec_inherit_mtx; 73 74 #endif 74 75 /** The mutex protecting the the globals and some shell instance members (sigs). */ … … 82 83 /** The number of shells. */ 83 84 static int volatile g_num_shells; 85 /* Statistics: Number of subshells spawned. */ 86 static KU64 g_stat_subshells = 0; 87 /* Statistics: Number of program exec'ed. */ 88 static KU64 volatile g_stat_execs = 0; 89 #if K_OS == K_OS_WINDOWS 90 /* Statistics: Number of serialized exec calls. */ 91 static KU64 volatile g_stat_execs_serialized = 0; 92 #endif 84 93 /** Per signal state for determining a common denominator. 85 94 * @remarks defaults and unmasked actions aren't counted. */ … … 172 181 if (psh->rootshell) 173 182 g_sh_root = psh; 183 else 184 g_stat_subshells++; 174 185 175 186 psh->next = NULL; … … 637 648 shmtx_init(&g_sh_mtx); 638 649 #ifndef SH_FORKED_MODE 639 shmtx_init(&g_sh_exec_ mtx);650 shmtx_init(&g_sh_exec_inherit_mtx); 640 651 #endif 641 652 … … 1660 1671 int rc; 1661 1672 1673 g_stat_execs++; 1674 1662 1675 #ifdef DEBUG 1663 1676 /* log it all */ … … 1698 1711 * This ain't quite straight forward on Windows... 1699 1712 */ 1700 #ifndef SH_FORKED_MODE1701 shmtxtmp tmp;1702 #endif1703 1713 PROCESS_INFORMATION ProcInfo; 1704 1714 STARTUPINFO StrtInfo; 1705 intptr_t hndls[3];1715 shfdexecwin fdinfo; 1706 1716 char *cwd = shfile_getcwd(&psh->fdtab, NULL, 0); 1707 1717 char *cmdline; … … 1812 1822 1813 1823 /* File handles. */ 1814 #ifndef SH_FORKED_MODE 1815 shmtx_enter(&g_sh_exec_mtx, &tmp); 1816 #endif 1817 StrtInfo.dwFlags |= STARTF_USESTDHANDLES; 1818 StrtInfo.lpReserved2 = shfile_exec_win(&psh->fdtab, 1 /* prepare */, &StrtInfo.cbReserved2, hndls); 1819 StrtInfo.hStdInput = (HANDLE)hndls[0]; 1820 StrtInfo.hStdOutput = (HANDLE)hndls[1]; 1821 StrtInfo.hStdError = (HANDLE)hndls[2]; 1824 fdinfo.strtinfo = &StrtInfo; 1825 shfile_exec_win(&psh->fdtab, 1 /* prepare */, &fdinfo); 1826 TRACE2((psh, "sh_execve: inherithandles=%d replacehandles={%d,%d,%d} handles={%p,%p,%p} suspended=%d Reserved2=%p LB %#x\n", 1827 fdinfo.inherithandles, fdinfo.replacehandles[0], fdinfo.replacehandles[1], fdinfo.replacehandles[2], 1828 fdinfo.handles[0], fdinfo.handles[1], fdinfo.handles[3], fdinfo.startsuspended, 1829 StrtInfo.lpReserved2, StrtInfo.cbReserved2)); 1830 if (!fdinfo.inherithandles) 1831 { 1832 StrtInfo.dwFlags |= STARTF_USESTDHANDLES; 1833 StrtInfo.hStdInput = INVALID_HANDLE_VALUE; 1834 StrtInfo.hStdOutput = INVALID_HANDLE_VALUE; 1835 StrtInfo.hStdError = INVALID_HANDLE_VALUE; 1836 } 1837 else 1838 { 1839 StrtInfo.dwFlags |= STARTF_USESTDHANDLES; 1840 StrtInfo.hStdInput = (HANDLE)fdinfo.handles[0]; 1841 StrtInfo.hStdOutput = (HANDLE)fdinfo.handles[1]; 1842 StrtInfo.hStdError = (HANDLE)fdinfo.handles[2]; 1843 g_stat_execs_serialized++; 1844 } 1822 1845 1823 1846 /* Get going... */ 1824 rc = CreateProcess(exe, 1825 cmdline, 1826 NULL, /* pProcessAttributes */ 1827 NULL, /* pThreadAttributes */ 1828 TRUE, /* bInheritHandles */ 1829 0, /* dwCreationFlags */ 1830 envblock, 1831 cwd, 1832 &StrtInfo, 1833 &ProcInfo); 1834 1835 shfile_exec_win(&psh->fdtab, rc ? 0 /* done */ : -1 /* done but failed */, NULL, NULL); 1836 #ifndef SH_FORKED_MODE 1837 shmtx_leave(&g_sh_exec_mtx, &tmp); 1838 #endif 1847 rc = CreateProcessA(exe, 1848 cmdline, 1849 NULL, /* pProcessAttributes */ 1850 NULL, /* pThreadAttributes */ 1851 fdinfo.inherithandles, 1852 fdinfo.startsuspended ? CREATE_SUSPENDED : 0, 1853 envblock, 1854 cwd, 1855 &StrtInfo, 1856 &ProcInfo); 1839 1857 if (rc) 1840 1858 { … … 1842 1860 DWORD dwExitCode; 1843 1861 1862 if (fdinfo.startsuspended) 1863 { 1864 char errmsg[512]; 1865 rc = nt_child_inject_standard_handles(ProcInfo.hProcess, fdinfo.replacehandles, (HANDLE*)&fdinfo.handles[0], 1866 errmsg, sizeof(errmsg)); 1867 if (!rc) 1868 { 1869 rc = ResumeThread(ProcInfo.hThread); 1870 if (!rc) 1871 TRACE2((psh, "sh_execve: ResumeThread failed: %u -> errno=ENXIO\n", GetLastError())); 1872 } 1873 else 1874 { 1875 TRACE2((psh, "sh_execve: nt_child_inject_standard_handles failed: %d -> errno=ENXIO; %s\n", rc, errmsg)); 1876 rc = FALSE; 1877 } 1878 errno = ENXIO; 1879 } 1880 1881 shfile_exec_win(&psh->fdtab, rc ? 0 /* done */ : -1 /* done but failed */, &fdinfo); 1882 1844 1883 CloseHandle(ProcInfo.hThread); 1845 dwErr = WaitForSingleObject(ProcInfo.hProcess, INFINITE); 1846 assert(dwErr == WAIT_OBJECT_0); 1847 1848 if (GetExitCodeProcess(ProcInfo.hProcess, &dwExitCode)) 1884 ProcInfo.hThread = INVALID_HANDLE_VALUE; 1885 if (rc) 1849 1886 { 1850 CloseHandle(ProcInfo.hProcess); 1851 sh__exit(psh, dwExitCode); 1887 /* 1888 * Wait for it and forward the exit code. 1889 */ 1890 dwErr = WaitForSingleObject(ProcInfo.hProcess, INFINITE); 1891 assert(dwErr == WAIT_OBJECT_0); 1892 1893 if (GetExitCodeProcess(ProcInfo.hProcess, &dwExitCode)) 1894 { 1895 #ifndef SH_FORKED_MODE 1896 /** @todo signal the end of this subshell now, we can do the cleaning up 1897 * after the parent shell has resumed. */ 1898 #endif 1899 CloseHandle(ProcInfo.hProcess); 1900 ProcInfo.hProcess = INVALID_HANDLE_VALUE; 1901 sh__exit(psh, dwExitCode); 1902 } 1903 1904 /* this shouldn't happen... */ 1905 TRACE2((psh, "sh_execve: GetExitCodeProcess failed: %u\n", GetLastError())); 1906 assert(0); 1907 errno = EINVAL; 1852 1908 } 1853 TRACE2((psh, "sh_execve: GetExitCodeProcess failed: %u\n", GetLastError())); 1854 assert(0); 1909 TerminateProcess(ProcInfo.hProcess, 0x40000015); 1855 1910 CloseHandle(ProcInfo.hProcess); 1856 errno = EINVAL;1857 1911 } 1858 1912 else 1859 1913 { 1860 1914 DWORD dwErr = GetLastError(); 1915 1916 shfile_exec_win(&psh->fdtab, -1 /* done but failed */, &fdinfo); 1917 1861 1918 switch (dwErr) 1862 1919 { … … 1865 1922 case ERROR_BAD_EXE_FORMAT: errno = ENOEXEC; break; 1866 1923 case ERROR_INVALID_EXE_SIGNATURE: errno = ENOEXEC; break; 1867 default: 1868 errno = EINVAL; 1869 break; 1924 default: errno = EINVAL; break; 1870 1925 } 1871 1926 TRACE2((psh, "sh_execve: dwErr=%d -> errno=%d\n", dwErr, errno)); 1872 1927 } 1873 1874 1928 } 1875 1929 rc = -1;
Note:
See TracChangeset
for help on using the changeset viewer.