Changeset 55605 in vbox
- Timestamp:
- May 2, 2015 8:30:26 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 99978
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r55604 r55605 126 126 # define USAGE_GSTCTRL_UPDATEGA RT_BIT(13) 127 127 # define USAGE_GSTCTRL_WATCH RT_BIT(14) 128 # define USAGE_GSTCTRL_EXEC RT_BIT(31) /**< @deprecated Remember to remove. */129 128 #endif 130 129 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r55604 r55605 347 347 /* 0 1 2 3 4 5 6 7 8XXXXXXXXXX */ 348 348 /* 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 */ 349 if (uSubCmd == USAGE_GSTCTRL_EXEC)350 RTStrmPrintf(pStrm,351 " {DEPRECATED} exec[ute]\n"352 " {DEPRECATED} --image <path to program> --username <name>\n"353 " {DEPRECATED} [--passwordfile <file> | --password <password>]\n"354 " {DEPRECATED} [--domain <domain>] [--verbose] [--timeout <msec>]\n"355 " {DEPRECATED} [--environment \"<NAME>=<VALUE> [<NAME>=<VALUE>]\"]\n"356 " {DEPRECATED} [--wait-exit] [--wait-stdout] [--wait-stderr]\n"357 " {DEPRECATED} [--dos2unix] [--unquoted-args] [--unix2dos]\n"358 " {DEPRECATED} [-- [<argument1>] ... [<argumentN>]]\n"359 "\n");360 349 if (uSubCmd & USAGE_GSTCTRL_COPYFROM) 361 350 RTStrmPrintf(pStrm, … … 411 400 if (uSubCmd & USAGE_GSTCTRL_CLOSEPROCESS) 412 401 RTStrmPrintf(pStrm, 413 " closeprocess |kill\n" COMMON_OPTION_HELP_ANON402 " closeprocess\n" COMMON_OPTION_HELP_ANON 414 403 " < --session-id <ID>\n" 415 404 " | --session-name <name or pattern>\n" … … 1509 1498 if (fRunCmd && pCtx->cVerbose > 1) 1510 1499 RTPrintf("Process '%s' (PID %RU32) started\n", pszImage, uPID); 1511 else if (!fRunCmd ) /** @todo Introduce a --quiet option for not printing this. */1500 else if (!fRunCmd && pCtx->cVerbose) 1512 1501 { 1513 1502 /* Just print plain PID to make it easier for scripts … … 1712 1701 } 1713 1702 1714 #if 1 /* Old exec code. */1715 1716 static int ctrlExecProcessStatusToExitCodeDeprecated(ProcessStatus_T enmStatus, ULONG uExitCode)1717 {1718 int vrc = RTEXITCODE_SUCCESS;1719 switch (enmStatus)1720 {1721 case ProcessStatus_Starting:1722 vrc = RTEXITCODE_SUCCESS;1723 break;1724 case ProcessStatus_Started:1725 vrc = RTEXITCODE_SUCCESS;1726 break;1727 case ProcessStatus_Paused:1728 vrc = RTEXITCODE_SUCCESS;1729 break;1730 case ProcessStatus_Terminating:1731 vrc = RTEXITCODE_SUCCESS;1732 break;1733 case ProcessStatus_TerminatedNormally:1734 vrc = !uExitCode ? RTEXITCODE_SUCCESS : EXITCODEEXEC_CODE;1735 break;1736 case ProcessStatus_TerminatedSignal:1737 vrc = EXITCODEEXEC_TERM_SIGNAL;1738 break;1739 case ProcessStatus_TerminatedAbnormally:1740 vrc = EXITCODEEXEC_TERM_ABEND;1741 break;1742 case ProcessStatus_TimedOutKilled:1743 vrc = EXITCODEEXEC_TIMEOUT;1744 break;1745 case ProcessStatus_TimedOutAbnormally:1746 vrc = EXITCODEEXEC_TIMEOUT;1747 break;1748 case ProcessStatus_Down:1749 /* Service/OS is stopping, process was killed, so1750 * not exactly an error of the started process ... */1751 vrc = EXITCODEEXEC_DOWN;1752 break;1753 case ProcessStatus_Error:1754 vrc = EXITCODEEXEC_FAILED;1755 break;1756 default:1757 AssertMsgFailed(("Unknown exit code (%u) from guest process returned!\n", enmStatus));1758 break;1759 }1760 return vrc;1761 }1762 1763 1764 /**1765 * Prints the desired guest output to a stream.1766 *1767 * @return IPRT status code.1768 * @param pProcess Pointer to appropriate process object.1769 * @param pStrmOutput Where to write the data.1770 * @param uHandle Handle where to read the data from.1771 * @param cMsTimeout Timeout (in ms) to wait for the operation to1772 * complete.1773 * @remarks Obsolete.1774 */1775 static int ctrlExecPrintOutputDeprecated(IProcess *pProcess, PRTSTREAM pStrmOutput,1776 ULONG uHandle, RTMSINTERVAL cMsTimeout)1777 {1778 AssertPtrReturn(pProcess, VERR_INVALID_POINTER);1779 AssertPtrReturn(pStrmOutput, VERR_INVALID_POINTER);1780 1781 int vrc = VINF_SUCCESS;1782 1783 SafeArray<BYTE> aOutputData;1784 HRESULT rc = pProcess->Read(uHandle, _64K, cMsTimeout,1785 ComSafeArrayAsOutParam(aOutputData));1786 if (SUCCEEDED(rc))1787 {1788 size_t cbOutputData = aOutputData.size();1789 if (cbOutputData > 0)1790 {1791 BYTE *pBuf = aOutputData.raw();1792 AssertPtr(pBuf);1793 pBuf[cbOutputData - 1] = 0; /* Properly terminate buffer. */1794 1795 /*1796 * If aOutputData is text data from the guest process' stdout or stderr,1797 * it has a platform dependent line ending. So standardize on1798 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on1799 * Windows. Otherwise we end up with CR/CR/LF on Windows.1800 */1801 1802 char *pszBufUTF8;1803 vrc = RTStrCurrentCPToUtf8(&pszBufUTF8, (const char*)aOutputData.raw());1804 if (RT_SUCCESS(vrc))1805 {1806 cbOutputData = strlen(pszBufUTF8);1807 1808 ULONG cbOutputDataPrint = (ULONG)cbOutputData;1809 for (char *s = pszBufUTF8, *d = s;1810 s - pszBufUTF8 < (ssize_t)cbOutputData;1811 s++, d++)1812 {1813 if (*s == '\r')1814 {1815 /* skip over CR, adjust destination */1816 d--;1817 cbOutputDataPrint--;1818 }1819 else if (s != d)1820 *d = *s;1821 }1822 1823 vrc = RTStrmWrite(pStrmOutput, pszBufUTF8, cbOutputDataPrint);1824 if (RT_FAILURE(vrc))1825 RTMsgError("Unable to write output, rc=%Rrc\n", vrc);1826 1827 RTStrFree(pszBufUTF8);1828 }1829 else1830 RTMsgError("Unable to convert output, rc=%Rrc\n", vrc);1831 }1832 }1833 else1834 vrc = gctlPrintError(pProcess, COM_IIDOF(IProcess));1835 return vrc;1836 }1837 1838 1839 static DECLCALLBACK(RTEXITCODE) gctlHandleProcessExecDeprecated(PGCTLCMDCTX pCtx)1840 {1841 AssertPtrReturn(pCtx, RTEXITCODE_FAILURE);1842 1843 /*1844 * Parse arguments.1845 */1846 static const RTGETOPTDEF s_aOptions[] =1847 {1848 GCTLCMD_COMMON_OPTION_DEFS()1849 { "--dos2unix", GETOPTDEF_EXEC_DOS2UNIX, RTGETOPT_REQ_NOTHING },1850 { "--environment", 'e', RTGETOPT_REQ_STRING },1851 { "--flags", 'f', RTGETOPT_REQ_STRING },1852 { "--ignore-operhaned-processes", GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES, RTGETOPT_REQ_NOTHING },1853 { "--image", 'i', RTGETOPT_REQ_STRING },1854 { "--no-profile", GETOPTDEF_EXEC_NO_PROFILE, RTGETOPT_REQ_NOTHING },1855 { "--timeout", 't', RTGETOPT_REQ_UINT32 },1856 { "--unix2dos", GETOPTDEF_EXEC_UNIX2DOS, RTGETOPT_REQ_NOTHING },1857 { "--unquoted-args", 'U', RTGETOPT_REQ_NOTHING },1858 { "--wait-exit", GETOPTDEF_EXEC_WAITFOREXIT, RTGETOPT_REQ_NOTHING },1859 { "--wait-stdout", GETOPTDEF_EXEC_WAITFORSTDOUT, RTGETOPT_REQ_NOTHING },1860 { "--wait-stderr", GETOPTDEF_EXEC_WAITFORSTDERR, RTGETOPT_REQ_NOTHING }1861 };1862 1863 int ch;1864 RTGETOPTUNION ValueUnion;1865 RTGETOPTSTATE GetState;1866 RTGetOptInit(&GetState, pCtx->pArg->argc, pCtx->pArg->argv, s_aOptions, RT_ELEMENTS(s_aOptions),1867 2, RTGETOPTINIT_FLAGS_OPTS_FIRST);1868 1869 Utf8Str strCmd;1870 com::SafeArray<ProcessCreateFlag_T> aCreateFlags;1871 com::SafeArray<ProcessWaitForFlag_T> aWaitFlags;1872 com::SafeArray<IN_BSTR> aArgsWithout0;1873 com::SafeArray<IN_BSTR> aArgsWith0;1874 com::SafeArray<IN_BSTR> aEnv;1875 RTMSINTERVAL cMsTimeout = 0;1876 bool fDetached = true;1877 int vrc = VINF_SUCCESS;1878 1879 try1880 {1881 /* Wait for process start in any case. This is useful for scripting VBoxManage1882 * when relying on its overall exit code. */1883 aWaitFlags.push_back(ProcessWaitForFlag_Start);1884 1885 while ( (ch = RTGetOpt(&GetState, &ValueUnion))1886 && RT_SUCCESS(vrc))1887 {1888 /* For options that require an argument, ValueUnion has received the value. */1889 switch (ch)1890 {1891 GCTLCMD_COMMON_OPTION_CASES(pCtx, ch, &ValueUnion);1892 1893 case 'e': /* Environment */1894 {1895 char **papszArg;1896 int cArgs;1897 1898 vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL);1899 if (RT_FAILURE(vrc))1900 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RUN,1901 "Failed to parse environment value, rc=%Rrc", vrc);1902 for (int j = 0; j < cArgs; j++)1903 aEnv.push_back(Bstr(papszArg[j]).raw());1904 1905 RTGetOptArgvFree(papszArg);1906 break;1907 }1908 1909 case GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES:1910 aCreateFlags.push_back(ProcessCreateFlag_IgnoreOrphanedProcesses);1911 break;1912 1913 case GETOPTDEF_EXEC_NO_PROFILE:1914 aCreateFlags.push_back(ProcessCreateFlag_NoProfile);1915 break;1916 1917 case 'i':1918 strCmd = ValueUnion.psz;1919 break;1920 1921 case 'U':1922 aCreateFlags.push_back(ProcessCreateFlag_UnquotedArguments);1923 break;1924 1925 /** @todo Add a hidden flag. */1926 1927 case 't': /* Timeout */1928 cMsTimeout = ValueUnion.u32;1929 break;1930 1931 case GETOPTDEF_EXEC_UNIX2DOS:1932 case GETOPTDEF_EXEC_DOS2UNIX:1933 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RUN,1934 "Output conversion not implemented yet!");1935 1936 case GETOPTDEF_EXEC_WAITFOREXIT:1937 aWaitFlags.push_back(ProcessWaitForFlag_Terminate);1938 fDetached = false;1939 break;1940 1941 case GETOPTDEF_EXEC_WAITFORSTDOUT:1942 aCreateFlags.push_back(ProcessCreateFlag_WaitForStdOut);1943 aWaitFlags.push_back(ProcessWaitForFlag_StdOut);1944 fDetached = false;1945 break;1946 1947 case GETOPTDEF_EXEC_WAITFORSTDERR:1948 aCreateFlags.push_back(ProcessCreateFlag_WaitForStdErr);1949 aWaitFlags.push_back(ProcessWaitForFlag_StdErr);1950 fDetached = false;1951 break;1952 1953 case VINF_GETOPT_NOT_OPTION:1954 if (aArgsWithout0.size() == 0 && strCmd.isEmpty())1955 strCmd = ValueUnion.psz;1956 else1957 aArgsWithout0.push_back(Bstr(ValueUnion.psz).raw());1958 break;1959 1960 default:1961 /* Note: Necessary for handling non-options (after --) which1962 * contain a single dash, e.g. "-- foo.exe -s". */1963 if (GetState.argc == GetState.iNext)1964 aArgsWithout0.push_back(Bstr(ValueUnion.psz).raw());1965 else1966 return errorGetOptEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RUN, ch, &ValueUnion);1967 break;1968 1969 } /* switch */1970 } /* while RTGetOpt */1971 1972 /* Create aArgsWith0 from strCmd and aArgsWithout0. */1973 aArgsWith0.push_back(Bstr(strCmd).raw());1974 for (size_t i = 0; i < aArgsWithout0.size(); i++)1975 aArgsWith0.push_back(aArgsWithout0[i]);1976 }1977 catch (std::bad_alloc &)1978 {1979 vrc = VERR_NO_MEMORY;1980 }1981 1982 if (RT_FAILURE(vrc))1983 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize, rc=%Rrc\n", vrc);1984 1985 if (strCmd.isEmpty())1986 return errorSyntaxEx(USAGE_GUESTCONTROL, USAGE_GSTCTRL_RUN,1987 "No command to execute specified!");1988 1989 RTEXITCODE rcExit = gctlCtxPostArgParsingInit(pCtx);1990 if (rcExit != RTEXITCODE_SUCCESS)1991 return rcExit;1992 1993 HRESULT rc;1994 1995 try1996 {1997 do1998 {1999 /* Adjust process creation flags if we don't want to wait for process termination. */2000 if (fDetached)2001 aCreateFlags.push_back(ProcessCreateFlag_WaitForProcessStartOnly);2002 2003 /* Get current time stamp to later calculate rest of timeout left. */2004 uint64_t u64StartMS = RTTimeMilliTS();2005 2006 if (pCtx->cVerbose > 1)2007 {2008 if (cMsTimeout == 0)2009 RTPrintf("Starting guest process ...\n");2010 else2011 RTPrintf("Starting guest process (within %ums)\n", cMsTimeout);2012 }2013 2014 /*2015 * Execute the process.2016 */2017 ComPtr<IGuestProcess> pProcess;2018 CHECK_ERROR_BREAK(pCtx->pGuestSession, ProcessCreate(Bstr(strCmd).raw(),2019 ComSafeArrayAsInParam(aArgsWith0),2020 ComSafeArrayAsInParam(aEnv),2021 ComSafeArrayAsInParam(aCreateFlags),2022 gctlRunGetRemainingTime(u64StartMS, cMsTimeout),2023 pProcess.asOutParam()));2024 2025 /*2026 * Explicitly wait for the guest process to be in a started2027 * state.2028 */2029 com::SafeArray<ProcessWaitForFlag_T> aWaitStartFlags;2030 aWaitStartFlags.push_back(ProcessWaitForFlag_Start);2031 ProcessWaitResult_T waitResult;2032 CHECK_ERROR_BREAK(pProcess, WaitForArray(ComSafeArrayAsInParam(aWaitStartFlags),2033 gctlRunGetRemainingTime(u64StartMS, cMsTimeout), &waitResult));2034 bool fCompleted = false;2035 2036 ULONG uPID = 0;2037 CHECK_ERROR_BREAK(pProcess, COMGETTER(PID)(&uPID));2038 if (!fDetached && pCtx->cVerbose > 1)2039 {2040 RTPrintf("Process '%s' (PID %RU32) started\n",2041 strCmd.c_str(), uPID);2042 }2043 else if (fDetached) /** @todo Introduce a --quiet option for not printing this. */2044 {2045 /* Just print plain PID to make it easier for scripts2046 * invoking VBoxManage. */2047 RTPrintf("[%RU32 - Session %RU32]\n", uPID, pCtx->uSessionID);2048 }2049 2050 vrc = RTStrmSetMode(g_pStdOut, 1 /* Binary mode */, -1 /* Code set, unchanged */);2051 if (RT_FAILURE(vrc))2052 RTMsgError("Unable to set stdout's binary mode, rc=%Rrc\n", vrc);2053 vrc = RTStrmSetMode(g_pStdErr, 1 /* Binary mode */, -1 /* Code set, unchanged */);2054 if (RT_FAILURE(vrc))2055 RTMsgError("Unable to set stderr's binary mode, rc=%Rrc\n", vrc);2056 2057 /* Wait for process to exit ... */2058 RTMSINTERVAL cMsTimeLeft = 1; /* Will be calculated. */2059 bool fReadStdOut, fReadStdErr;2060 fReadStdOut = fReadStdErr = false;2061 2062 while ( !fCompleted2063 && !fDetached2064 && cMsTimeLeft != 0)2065 {2066 cMsTimeLeft = gctlRunGetRemainingTime(u64StartMS, cMsTimeout);2067 CHECK_ERROR_BREAK(pProcess, WaitForArray(ComSafeArrayAsInParam(aWaitFlags),2068 500 /* ms */, &waitResult));2069 switch (waitResult)2070 {2071 case ProcessWaitResult_Start:2072 {2073 /* We're done here if we don't want to wait for termination. */2074 if (fDetached)2075 fCompleted = true;2076 2077 break;2078 }2079 case ProcessWaitResult_StdOut:2080 fReadStdOut = true;2081 break;2082 case ProcessWaitResult_StdErr:2083 fReadStdErr = true;2084 break;2085 case ProcessWaitResult_Terminate:2086 if (pCtx->cVerbose > 1)2087 RTPrintf("Process terminated\n");2088 /* Process terminated, we're done. */2089 fCompleted = true;2090 break;2091 case ProcessWaitResult_WaitFlagNotSupported:2092 {2093 /* The guest does not support waiting for stdout/err, so2094 * yield to reduce the CPU load due to busy waiting. */2095 RTThreadYield(); /* Optional, don't check rc. */2096 2097 /* Try both, stdout + stderr. */2098 fReadStdOut = fReadStdErr = true;2099 break;2100 }2101 case ProcessWaitResult_Timeout:2102 /* Fall through is intentional. */2103 default:2104 /* Ignore all other results, let the timeout expire */2105 break;2106 }2107 2108 if (g_fGuestCtrlCanceled)2109 break;2110 2111 if (fReadStdOut) /* Do we need to fetch stdout data? */2112 {2113 cMsTimeLeft = gctlRunGetRemainingTime(u64StartMS, cMsTimeout);2114 vrc = ctrlExecPrintOutputDeprecated(pProcess, g_pStdOut,2115 1 /* StdOut */, cMsTimeLeft);2116 fReadStdOut = false;2117 }2118 2119 if (fReadStdErr) /* Do we need to fetch stdout data? */2120 {2121 cMsTimeLeft = gctlRunGetRemainingTime(u64StartMS, cMsTimeout);2122 vrc = ctrlExecPrintOutputDeprecated(pProcess, g_pStdErr,2123 2 /* StdErr */, cMsTimeLeft);2124 fReadStdErr = false;2125 }2126 2127 if ( RT_FAILURE(vrc)2128 || g_fGuestCtrlCanceled)2129 break;2130 2131 /* Did we run out of time? */2132 if ( cMsTimeout2133 && RTTimeMilliTS() - u64StartMS > cMsTimeout)2134 break;2135 2136 NativeEventQueue::getMainEventQueue()->processEventQueue(0);2137 2138 } /* while */2139 2140 if (!fDetached)2141 {2142 /* Report status back to the user. */2143 if ( fCompleted2144 && !g_fGuestCtrlCanceled)2145 {2146 2147 {2148 ProcessStatus_T procStatus;2149 CHECK_ERROR_BREAK(pProcess, COMGETTER(Status)(&procStatus));2150 if ( procStatus == ProcessStatus_TerminatedNormally2151 || procStatus == ProcessStatus_TerminatedAbnormally2152 || procStatus == ProcessStatus_TerminatedSignal)2153 {2154 LONG exitCode;2155 CHECK_ERROR_BREAK(pProcess, COMGETTER(ExitCode)(&exitCode));2156 if (pCtx->cVerbose > 1)2157 RTPrintf("Exit code=%u (Status=%u [%s])\n",2158 exitCode, procStatus, gctlProcessStatusToText(procStatus));2159 2160 rcExit = (RTEXITCODE)ctrlExecProcessStatusToExitCodeDeprecated(procStatus, exitCode);2161 }2162 else if (pCtx->cVerbose > 1)2163 RTPrintf("Process now is in status [%s]\n", gctlProcessStatusToText(procStatus));2164 }2165 }2166 else2167 {2168 if (pCtx->cVerbose > 1)2169 RTPrintf("Process execution aborted!\n");2170 2171 rcExit = (RTEXITCODE)EXITCODEEXEC_TERM_ABEND;2172 }2173 }2174 2175 } while (0);2176 }2177 catch (std::bad_alloc)2178 {2179 rc = E_OUTOFMEMORY;2180 }2181 2182 /*2183 * Decide what to do with the guest session. If we started a2184 * detached guest process (that is, without waiting for it to exit),2185 * don't close the guest session it is part of.2186 */2187 bool fCloseSession = false;2188 if (SUCCEEDED(rc))2189 {2190 /*2191 * Only close the guest session if we waited for the guest2192 * process to exit. Otherwise we wouldn't have any chance to2193 * access and/or kill detached guest process lateron.2194 */2195 fCloseSession = !fDetached;2196 2197 /*2198 * If execution was aborted from the host side (signal handler),2199 * close the guest session in any case.2200 */2201 if (g_fGuestCtrlCanceled)2202 fCloseSession = true;2203 }2204 else /* Close session on error. */2205 fCloseSession = true;2206 2207 if (!fCloseSession)2208 pCtx->fDetachGuestSession = true;2209 2210 if ( rcExit == RTEXITCODE_SUCCESS2211 && FAILED(rc))2212 {2213 /* Make sure an appropriate exit code is set on error. */2214 rcExit = RTEXITCODE_FAILURE;2215 }2216 2217 return rcExit;2218 }2219 2220 #endif /* Old exec code. */2221 1703 2222 1704 /** … … 4711 4193 static const GCTLCMDDEF s_aCmdDefs[] = 4712 4194 { 4713 { "exec", gctlHandleProcessExecDeprecated,USAGE_GSTCTRL_EXEC, 0, },4714 { "execute", gctlHandleProcessExecDeprecated,USAGE_GSTCTRL_EXEC, 0, },4715 4195 { "run", gctlHandleRun, USAGE_GSTCTRL_RUN, 0, }, 4716 4196 { "start", gctlHandleStart, USAGE_GSTCTRL_START, 0, }, … … 4745 4225 { "stat", gctlHandleStat, USAGE_GSTCTRL_STAT, 0, }, 4746 4226 4747 /** @todo r=bird: these just work on processes we created, would be better to4748 * use some different command names here and leave the standard unix4749 * kill commands for killing/signalling ANY guest process, unix style. */4750 4227 { "closeprocess", gctlHandleCloseProcess, USAGE_GSTCTRL_CLOSEPROCESS, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, }, 4751 { "kill", gctlHandleCloseProcess, USAGE_GSTCTRL_CLOSEPROCESS, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, },4752 { "pkill", gctlHandleCloseProcess, USAGE_GSTCTRL_CLOSEPROCESS, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, },4753 { "pskill", gctlHandleCloseProcess, USAGE_GSTCTRL_CLOSEPROCESS, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, },4754 4755 4228 { "closesession", gctlHandleCloseSession, USAGE_GSTCTRL_CLOSESESSION, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, }, 4756 4229 { "list", gctlHandleList, USAGE_GSTCTRL_LIST, GCTLCMDCTX_F_SESSION_ANONYMOUS | GCTLCMDCTX_F_NO_SIGNAL_HANDLER, },
Note:
See TracChangeset
for help on using the changeset viewer.