HRESULT CModuleConfiguration::CreateNodeEnvironment(IHttpContext* ctx, DWORD debugPort, PCH namedPipe, PCH* env)
{
	HRESULT hr;
	LPCH currentEnvironment = NULL;
	LPCH tmpStart, tmpIndex = NULL;
	DWORD tmpSize;
	DWORD environmentSize;
	IAppHostElement* section = NULL;
	IAppHostElementCollection* appSettings = NULL;
	IAppHostElement* entry = NULL;
	IAppHostPropertyCollection* properties = NULL;
	IAppHostProperty* prop = NULL;
	BSTR keyPropertyName = NULL;
	BSTR valuePropertyName = NULL;
	VARIANT vKeyPropertyName;
	VARIANT vValuePropertyName;
	DWORD count;
	BSTR propertyValue;
	int propertySize;

	CheckNull(env);
	*env = NULL;

	// this is a zero terminated list of zero terminated strings of the form <var>=<value>

	// calculate size of current environment

	ErrorIf(NULL == (currentEnvironment = GetEnvironmentStrings()), GetLastError());
	environmentSize = 0;
	do {
		while (*(currentEnvironment + environmentSize++) != 0);
	} while (*(currentEnvironment + environmentSize++) != 0);

	// allocate memory for new environment variables

	tmpSize = 32767 - environmentSize;
	ErrorIf(NULL == (tmpIndex = tmpStart = new char[tmpSize]), ERROR_NOT_ENOUGH_MEMORY);
	RtlZeroMemory(tmpIndex, tmpSize);

	// set PORT and IISNODE_VERSION variables

	ErrorIf(tmpSize < (strlen(namedPipe) + strlen(IISNODE_VERSION) + 6 + 17), ERROR_NOT_ENOUGH_MEMORY);
	sprintf(tmpIndex, "PORT=%s", namedPipe);
	tmpIndex += strlen(namedPipe) + 6;
	sprintf(tmpIndex, "IISNODE_VERSION=%s", IISNODE_VERSION);
	tmpIndex += strlen(IISNODE_VERSION) + 17;

	// set DEBUGPORT environment variable if requested (used by node-inspector)

	if (debugPort > 0)
	{
		char debugPortS[64];
		sprintf(debugPortS, "%d", debugPort);
		ErrorIf((tmpSize - (tmpIndex - tmpStart)) < (strlen(debugPortS) + 11), ERROR_NOT_ENOUGH_MEMORY);
		sprintf(tmpIndex, "DEBUGPORT=%s", debugPortS);
		tmpIndex += strlen(debugPortS) + 11;
	}
		
	// add environment variables from the appSettings section of config

	ErrorIf(NULL == (keyPropertyName = SysAllocString(L"key")), ERROR_NOT_ENOUGH_MEMORY);
	vKeyPropertyName.vt = VT_BSTR;
	vKeyPropertyName.bstrVal = keyPropertyName;
	ErrorIf(NULL == (valuePropertyName = SysAllocString(L"value")), ERROR_NOT_ENOUGH_MEMORY);
	vValuePropertyName.vt = VT_BSTR;
	vValuePropertyName.bstrVal = valuePropertyName;
	CheckError(GetConfigSection(ctx, &section, L"appSettings"));
	CheckError(section->get_Collection(&appSettings));
	CheckError(appSettings->get_Count(&count));

	for (USHORT i = 0; i < count; i++)
	{
		VARIANT index;
		index.vt = VT_I2;
		index.iVal = i;		

		CheckError(appSettings->get_Item(index, &entry));
		CheckError(entry->get_Properties(&properties));
		
		CheckError(properties->get_Item(vKeyPropertyName, &prop));
		CheckError(prop->get_StringValue(&propertyValue));
		ErrorIf(0 == (propertySize = WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), NULL, 0, NULL, NULL)), E_FAIL);
		ErrorIf((propertySize + 2) > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY);
		ErrorIf(propertySize != WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), tmpIndex, propertySize, NULL, NULL), E_FAIL);
		tmpIndex[propertySize] = '=';
		tmpIndex += propertySize + 1;
		SysFreeString(propertyValue);
		propertyValue = NULL;
		prop->Release();
		prop = NULL;

		CheckError(properties->get_Item(vValuePropertyName, &prop));
		CheckError(prop->get_StringValue(&propertyValue));
		ErrorIf(0 == (propertySize = WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), NULL, 0, NULL, NULL)), E_FAIL);
		ErrorIf((propertySize + 1) > (tmpSize - (tmpStart - tmpIndex)), ERROR_NOT_ENOUGH_MEMORY);
		ErrorIf(propertySize != WideCharToMultiByte(CP_ACP, 0, propertyValue, wcslen(propertyValue), tmpIndex, propertySize, NULL, NULL), E_FAIL);
		tmpIndex += propertySize + 1;
		SysFreeString(propertyValue);
		propertyValue = NULL;
		prop->Release();
		prop = NULL;

		properties->Release();
		properties = NULL;
		entry->Release();
		entry = NULL;
	}

	// concatenate new environment variables with the current environment block

	ErrorIf(NULL == (*env = (LPCH)new char[environmentSize + (tmpIndex - tmpStart)]), ERROR_NOT_ENOUGH_MEMORY);	
	memcpy(*env, tmpStart, (tmpIndex - tmpStart));
	memcpy(*env + (tmpIndex - tmpStart), currentEnvironment, environmentSize);

	// cleanup

	FreeEnvironmentStrings(currentEnvironment);
	section->Release();
	appSettings->Release();
	SysFreeString(keyPropertyName);
	SysFreeString(valuePropertyName);
	delete [] tmpStart;

	return S_OK;
Error:

	if (currentEnvironment)
	{
		FreeEnvironmentStrings(currentEnvironment);
		currentEnvironment = NULL;
	}

	if (section)
	{
		section->Release();
		section = NULL;
	}

	if (appSettings)
	{
		appSettings->Release();
		appSettings = NULL;
	}

	if (keyPropertyName)
	{
		SysFreeString(keyPropertyName);
		keyPropertyName = NULL;
	}

	if (valuePropertyName)
	{
		SysFreeString(valuePropertyName);
		valuePropertyName = NULL;
	}

	if (entry)
	{
		entry->Release();
		entry = NULL;
	}

	if (properties)
	{
		properties->Release();
		properties = NULL;
	}

	if (prop)
	{
		prop->Release();
		prop = NULL;
	}

	if (propertyValue)
	{
		SysFreeString(propertyValue);
		propertyValue = NULL;
	}

	if (tmpStart)
	{
		delete [] tmpStart;
		tmpStart = NULL;
	}

	return hr;
}
int TestThreadCreateProcess(int argc, char* argv[])
{
	BOOL status;
	DWORD exitCode;
	LPCTSTR lpApplicationName;
	LPTSTR lpCommandLine;
	LPSECURITY_ATTRIBUTES lpProcessAttributes;
	LPSECURITY_ATTRIBUTES lpThreadAttributes;
	BOOL bInheritHandles;
	DWORD dwCreationFlags;
	LPVOID lpEnvironment;
	LPCTSTR lpCurrentDirectory;
	STARTUPINFO StartupInfo;
	PROCESS_INFORMATION ProcessInformation;
	LPTCH lpszEnvironmentBlock;
	HANDLE pipe_read = NULL;
	HANDLE pipe_write = NULL;
	char buf[255];
	DWORD read_bytes;
	int ret = 0;

	lpszEnvironmentBlock = GetEnvironmentStrings();

	lpApplicationName = NULL;
	//lpCommandLine = _T("ls -l /");

#ifdef _WIN32
	lpCommandLine = _T("env");
#else
	lpCommandLine = _T("printenv");
#endif

	lpProcessAttributes = NULL;
	lpThreadAttributes = NULL;
	bInheritHandles = FALSE;
	dwCreationFlags = 0;
	lpEnvironment = NULL;
	lpEnvironment = lpszEnvironmentBlock;
	lpCurrentDirectory = NULL;
	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
	StartupInfo.cb = sizeof(STARTUPINFO);
	ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));

	status = CreateProcess(lpApplicationName,
			lpCommandLine,
			lpProcessAttributes,
			lpThreadAttributes,
			bInheritHandles,
			dwCreationFlags,
			lpEnvironment,
			lpCurrentDirectory,
			&StartupInfo,
			&ProcessInformation);

	if (!status)
	{
		printf("CreateProcess failed. error=%d\n", GetLastError());
		return 1;
	}


	WaitForSingleObject(ProcessInformation.hProcess, INFINITE);

	exitCode = 0;
	status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);

	printf("GetExitCodeProcess status: %d\n", status);
	printf("Process exited with code: 0x%08X\n", exitCode);

	CloseHandle(ProcessInformation.hProcess);
	CloseHandle(ProcessInformation.hThread);
	FreeEnvironmentStrings(lpszEnvironmentBlock);

	/* Test stdin,stdout,stderr redirection */
	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
	StartupInfo.cb = sizeof(STARTUPINFO);
	ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));

	if (!CreatePipe(&pipe_read, &pipe_write, NULL, 0))
	{
		printf("Pipe creation failed. error=%d\n", GetLastError());
		return 1;
	}
	StartupInfo.hStdOutput = pipe_write;
	StartupInfo.hStdError = pipe_write;

	lpEnvironment = calloc(1, sizeof(TESTENV) + 1);
	strncpy(lpEnvironment, TESTENV, strlen(TESTENV));
	lpCommandLine = _T("printenv");

	status = CreateProcess(lpApplicationName,
						   lpCommandLine,
						   lpProcessAttributes,
						   lpThreadAttributes,
						   bInheritHandles,
						   dwCreationFlags,
						   lpEnvironment,
						   lpCurrentDirectory,
						   &StartupInfo,
						   &ProcessInformation);

	free(lpEnvironment);

	if (!status)
	{
		CloseHandle(pipe_read);
		CloseHandle(pipe_write);
		printf("CreateProcess failed. error=%d\n", GetLastError());
		return 1;
	}

	if (WaitForSingleObject(pipe_read, 200) != WAIT_OBJECT_0)
	{
		printf("pipe wait failed.\n");
		ret = 1;
	}
	else
	{
		ReadFile(pipe_read, buf, 255, &read_bytes, NULL);
		if (read_bytes < strlen(TESTENV))
		{
			printf("pipe read problem?!\n");
			ret = 1;
		}
	}

	WaitForSingleObject(ProcessInformation.hProcess, INFINITE);

	CloseHandle(pipe_read);
	CloseHandle(pipe_write);

	exitCode = 0;
	status = GetExitCodeProcess(ProcessInformation.hProcess, &exitCode);

	printf("GetExitCodeProcess status: %d\n", status);
	printf("Process exited with code: 0x%08X\n", exitCode);

	CloseHandle(ProcessInformation.hProcess);
	CloseHandle(ProcessInformation.hThread);

	return ret;
}
示例#3
0
void dynamic_context::set_environment_variables()
{
  if (!theEnvironmentVariables)
    theEnvironmentVariables = new EnvVarMap();

#if defined (WIN32)
    LPTCH envVarsCH = GetEnvironmentStrings();
    LPTSTR envVarsSTR = (LPTSTR) envVarsCH;

    while (*envVarsSTR)
    {
      int size = lstrlen(envVarsSTR);

      char * envVar = new char[size+1];

      WideCharToMultiByte( CP_ACP,
                           WC_NO_BEST_FIT_CHARS|WC_COMPOSITECHECK|WC_DEFAULTCHAR,
                           envVarsSTR,
                           size+1,
                           envVar,
                           size+1,
                           NULL,
                           NULL);

      zstring envVarZS(envVar);

      int eqPos = envVarZS.find_first_of("=");

      if (eqPos > 0)
      {
        zstring varname(envVarZS.substr(0, eqPos));
        zstring varvalue(envVarZS.substr(eqPos+1, size));

        if (!varname.empty() || !varvalue.empty())
          theEnvironmentVariables->insert(std::pair<zstring, zstring>(varname,varvalue));
      }

      delete envVar;
      envVarsSTR += lstrlen(envVarsSTR) + 1;
    }

    FreeEnvironmentStrings(envVarsCH);
#else
    const char* invalid_char;
    for (char **env = environ; *env; ++env)
    {
      zstring envVarZS(*env);

      if ((invalid_char = utf8::validate(envVarZS.c_str())) != NULL)
        throw XQUERY_EXCEPTION(err::FOCH0001,
          ERROR_PARAMS(zstring("#x") +
          BUILD_STRING(std::uppercase << std::hex
            << (static_cast<unsigned int>(*invalid_char)&0xFF))));

      if ((invalid_char = utf8::validate(envVarZS.c_str())) != NULL)
      {
        throw XQUERY_EXCEPTION(err::FOCH0001,
        ERROR_PARAMS(zstring("#x") +
        BUILD_STRING(std::uppercase << std::hex
                     << (static_cast<unsigned int>(*invalid_char) & 0xFF)) ));
      }

      int size = envVarZS.size();

      int eqPos = envVarZS.find_first_of("=");

      if (eqPos > 0)
      {
        zstring varname(envVarZS.substr(0, eqPos));
        zstring varvalue(envVarZS.substr(eqPos+1, size));

        if (!varname.empty() || !varvalue.empty())
          theEnvironmentVariables->insert(std::pair<zstring, zstring>(varname,varvalue));
      }
    }

#endif

}
示例#4
0
bool CWebServer::CallCGI(CWebClientSocket* pClient, CStringA& hdr, CStringA& body, CStringA& mime)
{
    CString path = pClient->m_path, redir = path;
    if (!ToLocalPath(path, redir)) {
        return false;
    }
    CString ext = CPath(path).GetExtension().MakeLower();
    CPath dir(path);
    dir.RemoveFileSpec();

    CString cgi;
    if (!m_cgi.Lookup(ext, cgi) || !CPath(cgi).FileExists()) {
        return false;
    }

    HANDLE hProcess = GetCurrentProcess();
    HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup = nullptr;
    HANDLE hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup = nullptr;

    SECURITY_ATTRIBUTES saAttr;
    ZeroMemory(&saAttr, sizeof(saAttr));
    saAttr.nLength = sizeof(saAttr);
    saAttr.bInheritHandle = TRUE;

    if (CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
        BOOL fSuccess = DuplicateHandle(hProcess, hChildStdoutRd, hProcess, &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
        UNREFERENCED_PARAMETER(fSuccess);
        CloseHandle(hChildStdoutRd);
    }

    if (CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
        BOOL fSuccess = DuplicateHandle(hProcess, hChildStdinWr, hProcess, &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
        UNREFERENCED_PARAMETER(fSuccess);
        CloseHandle(hChildStdinWr);
    }

    STARTUPINFO siStartInfo;
    ZeroMemory(&siStartInfo, sizeof(siStartInfo));
    siStartInfo.cb = sizeof(siStartInfo);
    siStartInfo.hStdError = hChildStdoutWr;
    siStartInfo.hStdOutput = hChildStdoutWr;
    siStartInfo.hStdInput = hChildStdinRd;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    siStartInfo.wShowWindow = SW_HIDE;

    PROCESS_INFORMATION piProcInfo;
    ZeroMemory(&piProcInfo, sizeof(piProcInfo));

    CStringA envstr;

    LPVOID lpvEnv = GetEnvironmentStrings();
    if (lpvEnv) {
        CAtlList<CString> env;
        for (LPTSTR lpszVariable = (LPTSTR)lpvEnv; *lpszVariable; lpszVariable += _tcslen(lpszVariable) + 1) {
            if (lpszVariable != (LPTSTR)lpvEnv) {
                env.AddTail(lpszVariable);
            }
        }

        env.AddTail(_T("GATEWAY_INTERFACE=CGI/1.1"));
        env.AddTail(_T("SERVER_SOFTWARE=MPC-HC/") MPC_VERSION_STR);
        env.AddTail(_T("SERVER_PROTOCOL=") + AToT(pClient->m_ver));
        env.AddTail(_T("REQUEST_METHOD=") + AToT(pClient->m_cmd));
        env.AddTail(_T("PATH_INFO=") + redir);
        env.AddTail(_T("PATH_TRANSLATED=") + path);
        env.AddTail(_T("SCRIPT_NAME=") + redir);
        env.AddTail(_T("QUERY_STRING=") + AToT(pClient->m_query));

        {
            CStringA str;
            if (pClient->m_hdrlines.Lookup("content-type", str)) {
                env.AddTail(_T("CONTENT_TYPE=") + AToT(str));
            }
            if (pClient->m_hdrlines.Lookup("content-length", str)) {
                env.AddTail(_T("CONTENT_LENGTH=") + AToT(str));
            }
        }

        POSITION pos = pClient->m_hdrlines.GetStartPosition();
        while (pos) {
            CString key = pClient->m_hdrlines.GetKeyAt(pos);
            CString value = pClient->m_hdrlines.GetNextValue(pos);
            key.Replace(_T("-"), _T("_"));
            key.MakeUpper();
            env.AddTail(_T("HTTP_") + key + _T("=") + value);
        }

        CString str, name;
        UINT port;

        if (pClient->GetPeerName(name, port)) {
            str.Format(_T("%u"), port);
            env.AddTail(_T("REMOTE_ADDR=") + name);
            env.AddTail(_T("REMOTE_HOST=") + name);
            env.AddTail(_T("REMOTE_PORT=") + str);
        }

        if (pClient->GetSockName(name, port)) {
            str.Format(_T("%u"), port);
            env.AddTail(_T("SERVER_NAME=") + name);
            env.AddTail(_T("SERVER_PORT=") + str);
        }

        env.AddTail(_T("\0"));

        str = Implode(env, '\0');
        envstr = CStringA(str, str.GetLength());

        FreeEnvironmentStrings((LPTSTR)lpvEnv);
    }

    TCHAR* cmdln = DEBUG_NEW TCHAR[32768];
    _sntprintf_s(cmdln, 32768, 32768, _T("\"%s\" \"%s\""), cgi, path);

    if (hChildStdinRd && hChildStdoutWr)
        if (CreateProcess(
                    nullptr, cmdln, nullptr, nullptr, TRUE, 0,
                    envstr.GetLength() ? (LPVOID)(LPCSTR)envstr : nullptr,
                    dir, &siStartInfo, &piProcInfo)) {
            DWORD ThreadId;
            CreateThread(nullptr, 0, KillCGI, (LPVOID)piProcInfo.hProcess, 0, &ThreadId);

            static const int BUFFSIZE = 1024;
            DWORD dwRead, dwWritten = 0;

            int i = 0, len = pClient->m_data.GetLength();
            for (; i < len; i += dwWritten) {
                if (!WriteFile(hChildStdinWrDup, (LPCSTR)pClient->m_data + i, min(len - i, BUFFSIZE), &dwWritten, nullptr)) {
                    break;
                }
            }

            CloseHandle(hChildStdinWrDup);
            CloseHandle(hChildStdoutWr);

            body.Empty();

            CStringA buff;
            while (i == len && ReadFile(hChildStdoutRdDup, buff.GetBuffer(BUFFSIZE), BUFFSIZE, &dwRead, nullptr) && dwRead) {
                buff.ReleaseBufferSetLength(dwRead);
                body += buff;
            }

            int hdrend = body.Find("\r\n\r\n");
            if (hdrend >= 0) {
                hdr = body.Left(hdrend + 2);
                body = body.Mid(hdrend + 4);
            }

            CloseHandle(hChildStdinRd);
            CloseHandle(hChildStdoutRdDup);

            CloseHandle(piProcInfo.hProcess);
            CloseHandle(piProcInfo.hThread);
        } else {
            body = _T("CGI Error");
        }

    delete [] cmdln;

    return true;
}
示例#5
0
Datum
plr_environ(PG_FUNCTION_ARGS)
{
	ReturnSetInfo	   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
	Tuplestorestate	   *tupstore;
	HeapTuple			tuple;
	TupleDesc			tupdesc;
	AttInMetadata	   *attinmeta;
	MemoryContext		per_query_ctx;
	MemoryContext		oldcontext;
	char			   *var_name;
	char			   *var_val;
	char			   *values[2];
#ifndef WIN32
	char			  **current_env;
#else
	char			   *buf;
	LPTSTR				envstr;
    int					count = 0;
	int					i;
#endif

	/* check to see if caller supports us returning a tuplestore */
	if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize))
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("materialize mode required, but it is not "
						"allowed in this context")));

	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
	oldcontext = MemoryContextSwitchTo(per_query_ctx);

	/* get the requested return tuple description */
	tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);

	/*
	 * Check to make sure we have a reasonable tuple descriptor
	 */
	if (tupdesc->natts != 2 ||
		tupdesc->attrs[0]->atttypid != TEXTOID ||
		tupdesc->attrs[1]->atttypid != TEXTOID)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("query-specified return tuple and "
						"function return type are not compatible")));

	/* OK to use it */
	attinmeta = TupleDescGetAttInMetadata(tupdesc);

	/* let the caller know we're sending back a tuplestore */
	rsinfo->returnMode = SFRM_Materialize;

	/* initialize our tuplestore */
	tupstore = TUPLESTORE_BEGIN_HEAP;

#ifndef WIN32
	for (current_env = environ;
		 current_env != NULL && *current_env != NULL;
		 current_env++)
	{
		Size	name_len;

		var_val = strchr(*current_env, '=');
		if (!var_val)
			continue;

		name_len = var_val - *current_env;
		var_name = (char *) palloc0(name_len + 1);
		memcpy(var_name, *current_env, name_len);

		values[0] = var_name;
		values[1] = var_val + 1;

		tuple = BuildTupleFromCStrings(attinmeta, values);
		tuplestore_puttuple(tupstore, tuple);
		pfree(var_name);
	}
#else	
	buf = GetEnvironmentStrings();
	envstr = buf;

	while (true)
	{
		if (*envstr == 0)
			break;
		while (*envstr != 0)
			envstr++;
		envstr++;
		count++;
	}
	/* reset pointer to the environment buffer */
	envstr = buf;

	while(*buf == '=')
		buf++;
	for (i = 0; i < count; i++)
	{
		Size	name_len;

		var_val = strchr(buf, '=');
		if (!var_val)
			continue;

		name_len = var_val - buf;
		var_name = (char *) palloc0(name_len + 1);
		memcpy(var_name, buf, name_len);

		values[0] = var_name;
		values[1] = var_val + 1;

		tuple = BuildTupleFromCStrings(attinmeta, values);
		tuplestore_puttuple(tupstore, tuple);
		pfree(var_name);
		
		while(*buf != '\0')
			buf++;
		buf++;
	}

	FreeEnvironmentStrings(envstr);
#endif
	
	/*
	 * no longer need the tuple descriptor reference created by
	 * TupleDescGetAttInMetadata()
	 */
	ReleaseTupleDesc(tupdesc);

	tuplestore_donestoring(tupstore);
	rsinfo->setResult = tupstore;

	/*
	 * SFRM_Materialize mode expects us to return a NULL Datum. The actual
	 * tuples are in our tuplestore and passed back through
	 * rsinfo->setResult. rsinfo->setDesc is set to the tuple description
	 * that we actually used to build our tuples with, so the caller can
	 * verify we did what it was expecting.
	 */
	rsinfo->setDesc = tupdesc;
	MemoryContextSwitchTo(oldcontext);

	return (Datum) 0;
}
示例#6
0
文件: doswind.c 项目: jossk/OrangeC
void FreeEnv(LPTCH env)
{
    FreeEnvironmentStrings(env);
    SetEnvironmentVariable("PATH", oldPath);
}
示例#7
0
文件: acl_env.c 项目: angel16364/acl
const char *acl_getenv_list(void)
{
	const char *myname = "acl_getenv_list";
#ifdef ACL_WINDOWS
	static acl_pthread_key_t buf_key = ACL_TLS_OUT_OF_INDEXES;
	ACL_VSTRING *buf;
	LPTSTR lpszVariable;
	LPVOID lpvEnv;
	int   i = 0, ch = 0;

	buf = (ACL_VSTRING*) acl_pthread_tls_get(&buf_key);
	if (buf == NULL) {
		if (buf_key == ACL_TLS_OUT_OF_INDEXES) {
			acl_msg_error("%s(%d): acl_pthread_tls_get error(%s)",
				myname, __LINE__, acl_last_serror());
			return (NULL);
		}
		buf = acl_vstring_alloc(256);
		acl_pthread_tls_set(buf_key, buf, (void (*)(void*)) free_vstring);
	} else
		ACL_VSTRING_RESET(buf);

	lpvEnv = GetEnvironmentStrings();
	for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) {
		if (i++ > 0)
			acl_vstring_strcat(buf, ", ");
		while (*lpszVariable) {
			ACL_VSTRING_ADDCH(buf, *lpszVariable++);
			ch = *lpszVariable;
		}
	}
	FreeEnvironmentStrings(lpvEnv);
	ACL_VSTRING_TERMINATE(buf);
	return (acl_vstring_str(buf));
#else
	static acl_pthread_key_t buf_key = (acl_pthread_key_t) ACL_TLS_OUT_OF_INDEXES;
	ACL_VSTRING *buf;
	extern char **environ;
	char **pptr = environ;
	int   i = 0;

	buf = (ACL_VSTRING*) acl_pthread_tls_get(&buf_key);
	if (buf == NULL) {
		if (buf_key == (acl_pthread_key_t) ACL_TLS_OUT_OF_INDEXES) {
			acl_msg_error("%s(%d): acl_pthread_tls_get error(%s)",
				myname, __LINE__, acl_last_serror());
			return (NULL);
		}
		buf = acl_vstring_alloc(256);
		acl_pthread_tls_set(buf_key, buf, (void (*)(void*)) free_vstring);
	} else
		ACL_VSTRING_RESET(buf);

	while (*pptr) {
		if (i++ > 0)
			acl_vstring_strcat(buf, ", ");
		acl_vstring_strcat(buf, *pptr);
		pptr++;
	}
	return (acl_vstring_str(buf));
#endif
}
示例#8
0
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
		LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
		LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
		LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
	pid_t pid;
	int flags;
	int numArgs;
	LPSTR* pArgs = NULL;
	char** envp = NULL;
	char* filename = NULL;
	HANDLE thread;
	HANDLE process;
	WINPR_ACCESS_TOKEN* token;
	LPTCH lpszEnvironmentBlock;
	BOOL ret = FALSE;

	pid = 0;
	numArgs = 0;
	lpszEnvironmentBlock = NULL;

	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);

	flags = 0;

	token = (WINPR_ACCESS_TOKEN*) hToken;

	if (lpEnvironment)
	{
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
	}
	else
	{
		lpszEnvironmentBlock = GetEnvironmentStrings();
		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
	}

	filename = FindApplicationPath(pArgs[0]);
	if (NULL == filename)
		goto finish;

	/* fork and exec */

	pid = fork();

	if (pid < 0)
	{
		/* fork failure */
		goto finish;
	}

	if (pid == 0)
	{
		/* child process */
#ifdef __sun
	closefrom(3);
#else
	int maxfd;
#ifdef F_MAXFD // on some BSD derivates
	maxfd = fcntl(0, F_MAXFD);
#else
	maxfd = sysconf(_SC_OPEN_MAX);
#endif
	int fd;
	for(fd=3; fd<maxfd; fd++)
		close(fd);
#endif // __sun

		if (token)
		{
			if (token->GroupId)
			{
				int rc = setgid((gid_t) token->GroupId);
				if (rc < 0)
				{
				}
				else
				{
					initgroups(token->Username, (gid_t) token->GroupId);
				}
			}

			if (token->UserId)
				setuid((uid_t) token->UserId);

			/* TODO: add better cwd handling and error checking */
			if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
				chdir(lpCurrentDirectory);
		}

		if (execve(filename, pArgs, envp) < 0)
		{
			/* execve failed - end the process */
			_exit(1);
		}
	}
	else
	{
		/* parent process */
	}

	process = CreateProcessHandle(pid);

	if (!process)
	{
		goto finish;
	}

	thread = CreateNoneHandle();

	if (!thread)
	{
		goto finish;
	}

	lpProcessInformation->hProcess = process;
	lpProcessInformation->hThread = thread;
	lpProcessInformation->dwProcessId = (DWORD) pid;
	lpProcessInformation->dwThreadId = (DWORD) pid;

	ret = TRUE;

finish:
	if (filename)
	{
		free(filename);
	}

	if (pArgs)
	{
		HeapFree(GetProcessHeap(), 0, pArgs);
	}

	if (lpszEnvironmentBlock)
		FreeEnvironmentStrings(lpszEnvironmentBlock);

	if (envp)
	{
		int i = 0;

		while (envp[i])
		{
			free(envp[i]);
			i++;
		}

		free(envp);
	}

	return ret;
}
示例#9
0
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
		LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
		LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
		LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
	pid_t pid;
	int flags;
	int numArgs;
	LPSTR* pArgs;
	char** envp;
	char* filename = NULL;
	WINPR_THREAD* thread;
	WINPR_PROCESS* process;
	WINPR_ACCESS_TOKEN* token;
	LPTCH lpszEnvironmentBlock;

	pid = 0;
	envp = NULL;
	numArgs = 0;
	lpszEnvironmentBlock = NULL;

	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);

	flags = 0;

	token = (WINPR_ACCESS_TOKEN*) hToken;

	if (lpEnvironment)
	{
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
	}
	else
	{
		lpszEnvironmentBlock = GetEnvironmentStrings();
		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
	}

	filename = FindApplicationPath(pArgs[0]);

	/* fork and exec */

	pid = fork();

	if (pid < 0)
	{
		/* fork failure */
		return FALSE;
	}

	if (pid == 0)
	{
		/* child process */
#ifdef __sun
	closefrom(3);
#else
	int maxfd;
#ifdef F_MAXFD // on some BSD derivates
	maxfd = fcntl(0, F_MAXFD);
#else
	maxfd = sysconf(_SC_OPEN_MAX);
#endif
	int fd;
	for(fd=3; fd<maxfd; fd++)
		close(fd);
#endif // __sun

		if (token)
		{
			if (token->GroupId)
			{
				setgid((gid_t) token->GroupId);
				initgroups(token->Username, (gid_t) token->GroupId);
			}

			if (token->UserId)
				setuid((uid_t) token->UserId);
		}

		if (execve(filename, pArgs, envp) < 0)
		{
			return FALSE;
		}
	}
	else
	{
		/* parent process */
	}

	process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS));

	if (!process)
		return FALSE;

	ZeroMemory(process, sizeof(WINPR_PROCESS));

	WINPR_HANDLE_SET_TYPE(process, HANDLE_TYPE_PROCESS);

	process->pid = pid;
	process->status = 0;
	process->dwExitCode = 0;

	thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD));

	ZeroMemory(thread, sizeof(WINPR_THREAD));

	if (!thread)
		return FALSE;

	WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD);

	thread->mainProcess = TRUE;

	lpProcessInformation->hProcess = (HANDLE) process;
	lpProcessInformation->hThread = (HANDLE) thread;
	lpProcessInformation->dwProcessId = (DWORD) pid;
	lpProcessInformation->dwThreadId = (DWORD) pid;

	free(filename);

	if (pArgs)
	{
		HeapFree(GetProcessHeap(), 0, pArgs);
	}

	if (lpszEnvironmentBlock)
		FreeEnvironmentStrings(lpszEnvironmentBlock);

	if (envp)
	{
		int i = 0;

		while (envp[i])
		{
			free(envp[i]);
			i++;
		}

		free(envp);
	}

	return TRUE;
}
示例#10
0
extern "C" CDECL rust_str *
rust_getcwd() {
    rust_task *task = rust_get_current_task();
    LOG(task, task, "rust_getcwd()");

    char cbuf[BUF_BYTES];

#if defined(__WIN32__)
    if (!_getcwd(cbuf, sizeof(cbuf))) {
#else
        if (!getcwd(cbuf, sizeof(cbuf))) {
#endif
        task->fail();
        return NULL;
    }

    return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)");
}

#if defined(__WIN32__)
extern "C" CDECL rust_vec_box *
rust_env_pairs() {
    rust_task *task = rust_get_current_task();
    size_t envc = 0;
    LPTCH ch = GetEnvironmentStringsA();
    LPTCH c;
    for (c = ch; *c; c += strlen(c) + 1) {
        ++envc;
    }
    c = ch;
    rust_vec_box *v = (rust_vec_box *)
        task->kernel->malloc(vec_size<rust_vec_box*>(envc),
                       "str vec interior");
    v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc;
    for (size_t i = 0; i < envc; ++i) {
        size_t n = strlen(c);
        rust_str *str = make_str(task->kernel, c, n, "str");
        ((rust_str**)&v->body.data)[i] = str;
        c += n + 1;
    }
    if (ch) {
        FreeEnvironmentStrings(ch);
    }
    return v;
}
#else
extern "C" CDECL rust_vec_box *
rust_env_pairs() {
    rust_task *task = rust_get_current_task();
#ifdef __APPLE__
    char **environ = *_NSGetEnviron();
#endif
    char **e = environ;
    size_t envc = 0;
    while (*e) {
        ++envc; ++e;
    }
    return make_str_vec(task->kernel, envc, environ);
}
#endif

extern "C" CDECL void
unsupervise() {
    rust_task *task = rust_get_current_task();
    task->unsupervise();
}
示例#11
0
文件: process.c 项目: FreeRDP/FreeRDP
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
                       LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
                       LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags,
                       LPVOID lpEnvironment,
                       LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
	pid_t pid;
	int numArgs;
	LPSTR* pArgs = NULL;
	char** envp = NULL;
	char* filename = NULL;
	HANDLE thread;
	HANDLE process;
	WINPR_ACCESS_TOKEN* token;
	LPTCH lpszEnvironmentBlock;
	BOOL ret = FALSE;
	sigset_t oldSigMask;
	sigset_t newSigMask;
	BOOL restoreSigMask = FALSE;
	numArgs = 0;
	lpszEnvironmentBlock = NULL;
	pArgs = CommandLineToArgvA(lpCommandLine, &numArgs);

	if (!pArgs)
		return FALSE;

	token = (WINPR_ACCESS_TOKEN*) hToken;

	if (lpEnvironment)
	{
		envp = EnvironmentBlockToEnvpA(lpEnvironment);
	}
	else
	{
		lpszEnvironmentBlock = GetEnvironmentStrings();

		if (!lpszEnvironmentBlock)
			goto finish;

		envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock);
	}

	if (!envp)
		goto finish;

	filename = FindApplicationPath(pArgs[0]);

	if (NULL == filename)
		goto finish;

	/* block all signals so that the child can safely reset the caller's handlers */
	sigfillset(&newSigMask);
	restoreSigMask = !pthread_sigmask(SIG_SETMASK, &newSigMask, &oldSigMask);
	/* fork and exec */
	pid = fork();

	if (pid < 0)
	{
		/* fork failure */
		goto finish;
	}

	if (pid == 0)
	{
		/* child process */
#ifndef __sun
		int maxfd;
#endif
		int fd;
		int sig;
		sigset_t set;
		struct sigaction act;
		/* set default signal handlers */
		memset(&act, 0, sizeof(act));
		act.sa_handler = SIG_DFL;
		act.sa_flags = 0;
		sigemptyset(&act.sa_mask);

		for (sig = 1; sig < NSIG; sig++)
			sigaction(sig, &act, NULL);

		/* unblock all signals */
		sigfillset(&set);
		pthread_sigmask(SIG_UNBLOCK, &set, NULL);

		if (lpStartupInfo)
		{
			int handle_fd;
			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdOutput);

			if (handle_fd != -1)
				dup2(handle_fd, STDOUT_FILENO);

			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdError);

			if (handle_fd != -1)
				dup2(handle_fd, STDERR_FILENO);

			handle_fd = winpr_Handle_getFd(lpStartupInfo->hStdInput);

			if (handle_fd != -1)
				dup2(handle_fd, STDIN_FILENO);
		}

#ifdef __sun
		closefrom(3);
#else
#ifdef F_MAXFD // on some BSD derivates
		maxfd = fcntl(0, F_MAXFD);
#else
		maxfd = sysconf(_SC_OPEN_MAX);
#endif

		for (fd = 3; fd < maxfd; fd++)
			close(fd);

#endif // __sun

		if (token)
		{
			if (token->GroupId)
			{
				int rc = setgid((gid_t) token->GroupId);

				if (rc < 0)
				{
				}
				else
				{
					initgroups(token->Username, (gid_t) token->GroupId);
				}
			}

			if (token->UserId)
				setuid((uid_t) token->UserId);
		}

		/* TODO: add better cwd handling and error checking */
		if (lpCurrentDirectory && strlen(lpCurrentDirectory) > 0)
			chdir(lpCurrentDirectory);

		if (execve(filename, pArgs, envp) < 0)
		{
			/* execve failed - end the process */
			_exit(1);
		}
	}
	else
	{
		/* parent process */
	}

	process = CreateProcessHandle(pid);

	if (!process)
	{
		goto finish;
	}

	thread = CreateNoneHandle();

	if (!thread)
	{
		ProcessHandleCloseHandle(process);
		goto finish;
	}

	lpProcessInformation->hProcess = process;
	lpProcessInformation->hThread = thread;
	lpProcessInformation->dwProcessId = (DWORD) pid;
	lpProcessInformation->dwThreadId = (DWORD) pid;
	ret = TRUE;
finish:

	/* restore caller's original signal mask */
	if (restoreSigMask)
		pthread_sigmask(SIG_SETMASK, &oldSigMask, NULL);

	free(filename);

	if (pArgs)
	{
		HeapFree(GetProcessHeap(), 0, pArgs);
	}

	if (lpszEnvironmentBlock)
		FreeEnvironmentStrings(lpszEnvironmentBlock);

	if (envp)
	{
		int i = 0;

		while (envp[i])
		{
			free(envp[i]);
			i++;
		}

		free(envp);
	}

	return ret;
}
示例#12
0
// Function name	: RunLocal
// Description	    : 
// Return type		: void 
// Argument         : bool bDoSMP
void RunLocal(bool bDoSMP)
{
	DWORD size = 100;
	TCHAR pszHost[100], pszCmdLine[MAX_PATH], error_msg[256], pszEnv[256], pszExtra[MAX_PATH];
	STARTUPINFO saInfo;
	PROCESS_INFORMATION psInfo;
	LPTSTR pEnv;
	int rootPort=0;
	HANDLE *hProcess = new HANDLE[g_nHosts];
			
	GetComputerName(pszHost, &size);

	wsprintf(pszCmdLine, TEXT("%s %s"), g_pszExe, g_pszArgs);

	GetTempFileName(_T("."), _T("mpi"), 0, pszExtra);
	// This produces a name in the form: ".\XXXmpi.tmp"
	// \ is illegal in named objects so use &pszExtra[2] instead of pszExtra for the JobID
	if (bDoSMP)
	{
		wsprintf(pszEnv, _T("MPICH_JOBID=%s|MPICH_IPROC=0|MPICH_NPROC=%d|MPICH_ROOTHOST=%s|MPICH_ROOTPORT=%d|MPICH_EXTRA=%s|MPICH_COMNIC=%s|MPICH_SHM_LOW=0|MPICH_SHM_HIGH=%d"),
				&pszExtra[2], g_nHosts, pszHost, -1, pszExtra, pszHost, g_nHosts-1);
	}
	else
	{
		wsprintf(pszEnv, _T("MPICH_JOBID=%s|MPICH_IPROC=0|MPICH_NPROC=%d|MPICH_ROOTHOST=%s|MPICH_ROOTPORT=%d|MPICH_EXTRA=%s|MPICH_COMNIC=%s"),
				&pszExtra[2], g_nHosts, pszHost, -1, pszExtra, pszHost);
	}

	SetEnvironmentVariables(pszEnv);
	if (_tcslen(g_pszEnv) > 0)
		SetEnvironmentVariables(g_pszEnv);
	pEnv = GetEnvironmentStrings();

	GetStartupInfo(&saInfo);

	// launch first process
	if (CreateProcess(
		NULL,
		pszCmdLine,
		NULL, NULL, FALSE,
		IDLE_PRIORITY_CLASS, 
		pEnv,
		NULL,
		&saInfo, &psInfo))
	{
		hProcess[0] = psInfo.hProcess;
		CloseHandle(psInfo.hThread);
	}
	else
	{
		int error = GetLastError();
		Translate_Error(error, error_msg, TEXT("CreateProcess failed: "));
		_tprintf(TEXT("Unable to launch '%s', error %d: %s"), pszCmdLine, error, error_msg);
		return;
	}

	RemoveEnvironmentVariables(pszEnv);
	FreeEnvironmentStrings(pEnv);

	if (g_bNoMPI)
	{
		rootPort = -1;
	}
	else
	{
		// Open the file and read the port number written by the first process
		HANDLE hFile = CreateFile(pszExtra, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
		if (hFile == INVALID_HANDLE_VALUE)
		{
			Translate_Error(GetLastError(), error_msg, TEXT("CreateFile failed "));
			_tprintf(error_msg);
			return;
		}
		
		DWORD num_read = 0;
		TCHAR pBuffer[100];
		pBuffer[0] = '\0';
		TCHAR *pChar = pBuffer;
		clock_t cStart = clock();
		while (true)
		{
			num_read = 0;
			if (!ReadFile(hFile, pChar, 100, &num_read, NULL))
			{
				Translate_Error(GetLastError(), error_msg, TEXT("ReadFile failed "));
				_tprintf(error_msg);
				return;
			}
			if (num_read == 0)
			{
				if (clock() - cStart > 10 * CLOCKS_PER_SEC)
				{
					_tprintf(TEXT("Wait for process 0 to write port to temporary file timed out\n"));
					TerminateProcess(hProcess, 0);
					return;
				}
				Sleep(100);
			}
			else
			{
				for (int i=0; i<(int)num_read; i++)
				{
					if (*pChar == _T('\n'))
						break;
					pChar ++;
				}
				if (*pChar == _T('\n'))
					break;
			}
		}
		CloseHandle(hFile);
		rootPort = _ttoi(pBuffer);
	}
	DeleteFile(pszExtra);

	// launch all the rest of the processes
	for (int i=1; i<g_nHosts; i++)
	{
		if (bDoSMP)
		{
			wsprintf(pszEnv, _T("MPICH_JOBID=%s|MPICH_IPROC=%d|MPICH_NPROC=%d|MPICH_ROOTHOST=%s|MPICH_ROOTPORT=%d|MPICH_COMNIC=%s|MPICH_SHM_LOW=0|MPICH_SHM_HIGH=%d"),
				&pszExtra[2], i, g_nHosts, pszHost, rootPort, pszHost, g_nHosts-1);
		}
		else
		{
			wsprintf(pszEnv, _T("MPICH_JOBID=%s|MPICH_IPROC=%d|MPICH_NPROC=%d|MPICH_ROOTHOST=%s|MPICH_ROOTPORT=%d|MPICH_COMNIC=%s"),
				&pszExtra[2], i, g_nHosts, pszHost, rootPort, pszHost);
		}
		
		SetEnvironmentVariables(pszEnv);
		pEnv = GetEnvironmentStrings();
		
		if (CreateProcess(
			NULL,
			pszCmdLine,
			NULL, NULL, FALSE,
			IDLE_PRIORITY_CLASS, 
			pEnv,
			NULL,
			&saInfo, &psInfo))
		{
			hProcess[i] = psInfo.hProcess;
			CloseHandle(psInfo.hThread);
		}
		else
		{
			int error = GetLastError();
			Translate_Error(error, error_msg, TEXT("CreateProcess failed: "));
			_tprintf(TEXT("Unable to launch '%s', error %d: %s"), pszCmdLine, error, error_msg);
			return;
		}
		
		RemoveEnvironmentVariables(pszEnv);
		FreeEnvironmentStrings(pEnv);
	}

	// Wait for all the processes to terminate
	WaitForLotsOfObjects(g_nHosts, hProcess);

	for (i=0; i<g_nHosts; i++)
		CloseHandle(hProcess[i]);
	delete hProcess;
}
示例#13
0
void mhmakefileparser::SetExport(const string &Var, const string &Val)
{
  m_Exports.insert(Var);
#ifdef WIN32
  if (!m_pEnv)
  {
    /* Environment not created yet, so create one */
    char *pEnv=GetEnvironmentStrings();
    char *pEnd=pEnv;
    while (*pEnd)
    {
      while (*pEnd++);
    }
    size_t Len=pEnd-pEnv+1;
    m_pEnv=(char*)malloc(Len);
    memcpy(m_pEnv,pEnv,Len);
    m_EnvLen=Len;
    FreeEnvironmentStrings(pEnv);
  }
  /* First check if the variable is in the environment, if so remove it first */
  char *pEnv=m_pEnv;
  while (*pEnv)
  {
    const char *pVar=Var.c_str();
    char *pStart=pEnv;
    while (*pEnv!='=' && tolower(*pEnv)==tolower(*pVar))
    {
      pEnv++; pVar++;
    }
    if (*pEnv=='=' && !*pVar)
    {
      /* Variable found, remove it */
      while (*pEnv++);
      m_EnvLen-=pEnv-pStart;
      while (*pEnv)
      {
        while (*pEnv)
        {
          *pStart=*pEnv++;
          pStart++;
        }
        *pStart=*pEnv++;
        pStart++;
      }
      *pStart=*pEnv;
      break;
    }
    while (*pEnv++);
  }
  size_t VarLen=Var.length();
  size_t ValLen=Val.length();
  size_t Extra=VarLen+ValLen+2;
  /* Add the variable at the end */
  m_pEnv=(char*)realloc(m_pEnv,m_EnvLen+Extra);
  pEnv=m_pEnv+m_EnvLen-1;
  memcpy(pEnv,Var.c_str(),VarLen);
  pEnv+=VarLen;
  *pEnv++='=';
  memcpy(pEnv,Val.c_str(),ValLen);
  pEnv+=ValLen;
  *pEnv++='\0';
  *pEnv++='\0';
  m_EnvLen+=Extra;
#else
  if (!m_pEnv)
  {
    /* Environment not created yet, so create one */
    char **pEnv=environ;
    char **pEnd=pEnv;
    int Len=1;
    while (*pEnd)
    {
      Len++;
      pEnd++;
    }
    m_EnvLen=Len;
    m_pEnv=(char**)malloc(Len*sizeof(pEnv));
    int i=0;
    while (*pEnv)
    {
      m_pEnv[i]=strdup(*pEnv);
      i++;
      pEnv++;
    }
    m_pEnv[i]=NULL;
  }
  /* First check if the variable is in the environment, if so replace it */
  char **pEnv=m_pEnv;
  while (*pEnv)
  {
    const char *pVar=Var.c_str();
    char *pStart=*pEnv;
    char *pTmp=pStart;
    while (*pTmp!='=' && *pTmp==*pVar)
    {
      pTmp++; pVar++;
    }
    if (*pTmp=='=' && !*pVar)
    {
      free(*pEnv);
      *pEnv=strdup((Var+"="+Val).c_str());
      break;
    }
    pEnv++;
  }
  if (!*pEnv)
  {
    // Add it at the end of the list
    m_pEnv=(char**)realloc(m_pEnv,(m_EnvLen+1)*sizeof(*pEnv));
    m_pEnv[m_EnvLen-1]=strdup((Var+"="+Val).c_str());
    m_pEnv[m_EnvLen++]=NULL;
  }

#endif
}