tstRTProcCreateEx.cpp revision eb164f7d77f5b3bee0fe6fbdd46521550e3306c4
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/* $Id$ */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/** @file
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * IPRT Testcase - RTProcCreateEx.
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2010 Oracle Corporation
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync *
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * available from http://www.virtualbox.org. This file is free software;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * you can redistribute it and/or modify it under the terms of the GNU
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * General Public License (GPL) as published by the Free Software
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync *
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * The contents of this file may alternatively be used under the terms
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * of the Common Development and Distribution License Version 1.0
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * VirtualBox OSE distribution, in which case the provisions of the
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * CDDL are applicable instead of those of the GPL.
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync *
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * You may elect to license modified versions of this file under the
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync * terms and conditions of either the GPL or the CDDL or both.
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/*******************************************************************************
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync* Header Files *
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync*******************************************************************************/
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/process.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/assert.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/env.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/err.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/initterm.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/mem.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/message.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/param.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/pipe.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/string.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/stream.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/test.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#include <iprt/thread.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#ifdef RT_OS_WINDOWS
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync# define SECURITY_WIN32
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync# include <windows.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync# include <Security.h>
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#endif
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/*******************************************************************************
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync* Global Variables *
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync*******************************************************************************/
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic char g_szExecName[RTPATH_MAX];
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic const char * const g_apszArgs4[] =
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 0 */ "non existing non executable file",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 1 */ "--testcase-child-4",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 2 */ "a b",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 3 */ " cdef",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 4 */ "ghijkl ",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 5 */ "\"",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 6 */ "\\",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 7 */ "\\\"",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 8 */ "\\\"\\",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* 9 */ "\\\\\"\\",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync};
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic int tstRTCreateProcEx5Child(int argc, char **argv)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync int rc = RTR3InitExeNoArguments(0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (rc)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return RTMsgInitFailure(rc);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#ifdef RT_OS_WINDOWS
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync char szUser[_1K];
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync DWORD cbLen = sizeof(szUser);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /** @todo Does not yet handle ERROR_MORE_DATA for user names longer than 32767. */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (!GetUserName(szUser, &cbLen))
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPrintf("GetUserName failed with last error=%ld\n", GetLastError());
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return VERR_AUTHENTICATION_FAILURE;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync else
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync/* Does not work on NT4 (yet). */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#if 0
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync DWORD cbSid = 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync DWORD cbDomain = 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync SID_NAME_USE sidUse;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* First try to figure out how much space for SID + domain name we need. */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync BOOL bRet = LookupAccountName(NULL /* current system*/,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync szUser,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &cbSid,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &cbDomain,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &sidUse);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (!bRet)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync DWORD dwErr = GetLastError();
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (dwErr != ERROR_INSUFFICIENT_BUFFER)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPrintf("LookupAccountName(1) failed with last error=%ld\n", dwErr);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return VERR_AUTHENTICATION_FAILURE;
14380feae039b4eb5a70e053e186000c706ff358vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* Now try getting the real SID + domain name. */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync SID *pSid = (SID *)RTMemAlloc(cbSid);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync AssertPtr(pSid);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync char *pszDomain = (char *)RTMemAlloc(cbDomain); /* Size in TCHAR! */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync AssertPtr(pszDomain);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (!LookupAccountName(NULL /* Current system */,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync szUser,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync pSid,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &cbSid,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync pszDomain,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &cbDomain,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &sidUse))
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPrintf("LookupAccountName(2) failed with last error=%ld\n", GetLastError());
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return VERR_AUTHENTICATION_FAILURE;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTMemFree(pSid);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTMemFree(pszDomain);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#endif
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#else
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /** @todo Lookup UID/effective UID, maybe GID? */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync#endif
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return rc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic void tstRTCreateProcEx5(const char *pszUser, const char *pszPassword)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestISubF("As user \"%s\" with password \"%s\"", pszUser, pszPassword);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync const char * apszArgs[3] =
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "test", /* user name */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "--testcase-child-5",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCESS hProc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* Test for invalid logons. */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL, NULL, "non-existing-user", "wrong-password", &hProc), VERR_AUTHENTICATION_FAILURE);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* Test for invalid application. */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync /* Test a (hopefully) valid user/password logon (given by parameters of this function). */
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL, NULL, pszUser, pszPassword, &hProc), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync else
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIPassed(NULL);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic int tstRTCreateProcEx4Child(int argc, char **argv)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync int rc = RTR3InitExeNoArguments(0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (rc)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return RTMsgInitFailure(rc);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync for (int i = 0; i < argc; i++)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (strcmp(argv[i], g_apszArgs4[i]))
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdErr,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "child4: argv[%2u]='%s'\n"
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "child4: expected='%s'\n",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync i, argv[i], g_apszArgs4[i]);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync rc++;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return rc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic void tstRTCreateProcEx4(void)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestISub("Argument with spaces and stuff");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCESS hProc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, g_apszArgs4, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL, NULL, NULL, NULL, &hProc), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync else
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIPassed(NULL);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic int tstRTCreateProcEx3Child(void)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync int rc = RTR3InitExeNoArguments(0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (rc)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return RTMsgInitFailure(rc);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdOut, "w"); RTStrmFlush(g_pStdOut);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdErr, "o"); RTStrmFlush(g_pStdErr);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdOut, "r"); RTStrmFlush(g_pStdOut);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdErr, "k"); RTStrmFlush(g_pStdErr);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdOut, "s");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic void tstRTCreateProcEx3(void)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestISub("Standard Out+Err");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPIPE hPipeR, hPipeW;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync const char * apszArgs[3] =
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "non-existing-non-executable-file",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "--testcase-child-3",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTHANDLE Handle;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync Handle.enmType = RTHANDLETYPE_PIPE;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync Handle.u.hPipe = hPipeW;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCESS hProc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync &Handle, &Handle, NULL, NULL, &hProc), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync char szOutput[_4K];
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync size_t offOutput = 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync for (;;)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync size_t cbLeft = sizeof(szOutput) - 1 - offOutput;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK(cbLeft > 0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (cbLeft == 0)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync break;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync size_t cbRead;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync int rc = RTPipeReadBlocking(hPipeR, &szOutput[offOutput], cbLeft, &cbRead);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (RT_FAILURE(rc))
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(rc, VERR_BROKEN_PIPE);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync break;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync offOutput += cbRead;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync }
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync szOutput[offOutput] = '\0';
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTThreadSleep(10);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync else if ( offOutput != sizeof("works") - 1
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync || strcmp(szOutput, "works"))
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync else
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestIPassed(NULL);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic int tstRTCreateProcEx2Child(void)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync int rc = RTR3InitExeNoArguments(0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (rc)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return RTMsgInitFailure(rc);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdErr, "howdy");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTStrmPrintf(g_pStdOut, "ignore this output\n");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync return 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync}
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsyncstatic void tstRTCreateProcEx2(void)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync{
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTestISub("Standard Err");
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPIPE hPipeR, hPipeW;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync const char * apszArgs[3] =
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "non-existing-non-executable-file",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync "--testcase-child-2",
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync };
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTHANDLE Handle;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync Handle.enmType = RTHANDLETYPE_PIPE;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync Handle.u.hPipe = hPipeW;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTPROCESS hProc;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync NULL, &Handle, NULL, NULL, &hProc), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync char szOutput[_4K];
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync size_t offOutput = 0;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync for (;;)
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync {
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync size_t cbLeft = sizeof(szOutput) - 1 - offOutput;
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync RTTESTI_CHECK(cbLeft > 0);
3183efc91c7b8252f1dc50dca3efd2d8ae627813vboxsync if (cbLeft == 0)
break;
size_t cbRead;
int rc = RTPipeReadBlocking(hPipeR, &szOutput[offOutput], cbLeft, &cbRead);
if (RT_FAILURE(rc))
{
RTTESTI_CHECK_RC(rc, VERR_BROKEN_PIPE);
break;
}
offOutput += cbRead;
}
szOutput[offOutput] = '\0';
RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
RTThreadSleep(10);
if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
else if ( offOutput != sizeof("howdy") - 1
|| strcmp(szOutput, "howdy"))
RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput);
else
RTTestIPassed(NULL);
}
static int tstRTCreateProcEx1Child(void)
{
int rc = RTR3InitExeNoArguments(0);
if (rc)
return RTMsgInitFailure(rc);
RTPrintf("it works");
RTStrmPrintf(g_pStdErr, "ignore this output\n");
return 0;
}
static void tstRTCreateProcEx1(void)
{
RTTestISub("Standard Out");
RTPIPE hPipeR, hPipeW;
RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
const char * apszArgs[3] =
{
"non-existing-non-executable-file",
"--testcase-child-1",
NULL
};
RTHANDLE Handle;
Handle.enmType = RTHANDLETYPE_PIPE;
Handle.u.hPipe = hPipeW;
RTPROCESS hProc;
RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
&Handle, NULL, NULL, NULL, &hProc), VINF_SUCCESS);
RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
char szOutput[_4K];
size_t offOutput = 0;
for (;;)
{
size_t cbLeft = sizeof(szOutput) - 1 - offOutput;
RTTESTI_CHECK(cbLeft > 0);
if (cbLeft == 0)
break;
size_t cbRead;
int rc = RTPipeReadBlocking(hPipeR, &szOutput[offOutput], cbLeft, &cbRead);
if (RT_FAILURE(rc))
{
RTTESTI_CHECK_RC(rc, VERR_BROKEN_PIPE);
break;
}
offOutput += cbRead;
}
szOutput[offOutput] = '\0';
RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus);
else if ( offOutput != sizeof("it works") - 1
|| strcmp(szOutput, "it works"))
RTTestIFailed("wrong output: \"%s\" (len=%u)", szOutput, offOutput);
else
RTTestIPassed(NULL);
}
int main(int argc, char **argv)
{
if (argc == 2 && !strcmp(argv[1], "--testcase-child-1"))
return tstRTCreateProcEx1Child();
if (argc == 2 && !strcmp(argv[1], "--testcase-child-2"))
return tstRTCreateProcEx2Child();
if (argc == 2 && !strcmp(argv[1], "--testcase-child-3"))
return tstRTCreateProcEx3Child();
if (argc >= 5 && !strcmp(argv[1], "--testcase-child-4"))
return tstRTCreateProcEx4Child(argc, argv);
if (argc == 2 && !strcmp(argv[1], "--testcase-child-5"))
return tstRTCreateProcEx5Child(argc, argv);
const char *pszAsUser = NULL;
const char *pszPassword = NULL;
if (argc != 1)
{
if (argc != 4 || strcmp(argv[1], "--as-user"))
return 99;
pszAsUser = argv[2];
pszPassword = argv[3];
}
RTTEST hTest;
int rc = RTTestInitAndCreate("tstRTProcCreateEx", &hTest);
if (rc)
return rc;
RTTestBanner(hTest);
if (!RTProcGetExecutablePath(g_szExecName, sizeof(g_szExecName)))
RTStrCopy(g_szExecName, sizeof(g_szExecName), argv[0]);
/*
* The tests.
*/
tstRTCreateProcEx1();
tstRTCreateProcEx2();
tstRTCreateProcEx3();
tstRTCreateProcEx4();
if (pszAsUser)
tstRTCreateProcEx5(pszAsUser, pszPassword);
/** @todo Cover files, ++ */
/*
* Summary.
*/
return RTTestSummaryAndDestroy(hTest);
}