示例#1
0
int ESvnBase::ContinuePipe () {
    char RealCommand[2048];
    size_t space;

    if (!OnFilesPos) {
        // At the end of all files, terminate
        ClosePipe ();
        return 0;
    } else if (Running) {
        // Already running, close the pipe and continue
        ReturnCode=gui->ClosePipe (PipeId);
    } else {
        // Not running -> set to Running mode
        Running=1;
    }

    // Make real command with some files from OnFiles, update OnFilesPos
    strcat (strcpy (RealCommand,Command)," ");
    space=sizeof (RealCommand)-strlen (RealCommand)-1;
    if (space>=strlen (OnFilesPos)) {
        strcat (RealCommand,OnFilesPos);
        OnFilesPos=NULL;
    } else {
        char c=OnFilesPos[space];
        OnFilesPos[space]=0;
        char *s=strrchr (OnFilesPos,' ');
        OnFilesPos[space]=c;
        if (!s) {
            ClosePipe ();
            return 0;
        }
        *s=0;
        strcat (RealCommand,OnFilesPos);
        OnFilesPos=s+1;
        while (*OnFilesPos==' ') OnFilesPos++;
        if (!*OnFilesPos) OnFilesPos=NULL;
    }

    BufLen=BufPos=0;

    {
        char s[sizeof (RealCommand)+32];

        sprintf (s,"[continuing: '%s']",RealCommand);
        AddLine (0,-1,s);
    }

    PipeId=gui->OpenPipe (RealCommand,this);
    return 0;
}
示例#2
0
文件: Pipe.cpp 项目: dmead/sc2bot
void Pipe::ConnectToPipe(const String &PipeName)
{
    ClosePipe();
    bool Done = false;
    while(!Done)
    {
        _Handle = CreateFile( 
            PipeName.CString(),           // pipe name 
            GENERIC_READ |                // read and write access 
            GENERIC_WRITE, 
            0,                            // no sharing 
            NULL,                         // default security attributes
            OPEN_EXISTING,                // opens existing pipe 
            0,                            // default attributes 
            NULL);                        // no template file
        if(_Handle != INVALID_HANDLE_VALUE)
        {
            Done = true;
        }
        Sleep(100);
    }

    DWORD Mode = PIPE_READMODE_MESSAGE;
    BOOL Success = SetNamedPipeHandleState( 
        _Handle,  // pipe handle 
        &Mode,    // new pipe mode 
        NULL,     // don't set maximum bytes 
        NULL);    // don't set maximum time 
    Assert(Success != FALSE, "SetNamedPipeHandleState failed in Pipe::ConnectToPipe");
}
示例#3
0
/***********************************************************************************
 ** Execute a file chooser dialog
 ** NB: this will fork
 **
 ** KDEOpFileChooser::Execute
 ***********************************************************************************/
OP_STATUS KDEOpFileChooser::Execute(OpWindow* parent,
									DesktopFileChooserListener* listener,
									const DesktopFileChooserRequest& request)
{
	// Don't call twice
	if (m_childpid)
		return OpStatus::ERR;

	m_listener = listener;

	// Prepare communication pipe
	if (pipe(m_pipe_descriptor) != 0)
		return OpStatus::ERR;

	// fork() and check for error
	m_childpid = fork();

	if (m_childpid == 0)
	{
		// Child
		ClosePipe(PipeRead);
		dup2(m_pipe_descriptor[PipeWrite], fileno(stdout));

		if (OpStatus::IsError(OpenDialog(request)))
			exit(1);
	}
	else if (m_childpid > 0)
	{
		// Parent
		ClosePipe(PipeWrite);

		g_main_message_handler->SetCallBack(this, MSG_FILE_CHOOSER_SHOW, reinterpret_cast<MH_PARAM_1>(this));
		g_main_message_handler->PostMessage(MSG_FILE_CHOOSER_SHOW, reinterpret_cast<MH_PARAM_1>(this), 0, 100);
	}
	else
	{
		// Error occured
		m_childpid = 0;
		return OpStatus::ERR;
	}

	return OpStatus::OK;
}
示例#4
0
static BOOL ProcessDetach()
{
    lf("memtrace.dll: ProcessDetach()");
    TerminateSendingThread();
    ClosePipe();
    DeleteCriticalSection(&gMemMutex);
    CloseHandle(gSendThreadEvent);
    FreeAllBlocks();
    lf("memtrace.dll: allocated total %d blocks", gBlocksAllocated);
    HeapDestroy(gHeap);
    return TRUE;
}
示例#5
0
static bool WriteToPipe(const byte *s, size_t len)
{
    DWORD written;
    if (!gPipe)
        return false;
    DWORD toWrite = (DWORD)len;
    BOOL ok = WriteFile(gPipe, s, toWrite, &written, NULL);
    if (!ok) {
        lf("memtrace.dll: WriteToPipe() failed");
        LogLastError();
        ClosePipe();
        return false;
    }

    if (written != toWrite) {
        lf("memtrace.dll: only wrote %d out of %d", (int)written, (int)toWrite);
        ClosePipe();
        return false;
    }
    return true;
}
示例#6
0
void
std_logger_Close(std_logger *sys)
{
    if (sys->stop_pipe[1] != -1)
    {
        write(sys->stop_pipe[1], '\0', 1);
        close(sys->stop_pipe[1]);
        sys->stop_pipe[1] = -1;
        pthread_join(sys->thread, NULL);
    }
    ClosePipe(sys->stop_pipe);
    ClosePipe(sys->stdout_pipe);
    ClosePipe(sys->stderr_pipe);

    if (sys->old_stdout != -1 && sys->old_stderr != -1) {
        dup2(sys->old_stdout, STDOUT_FILENO);
        dup2(sys->old_stderr, STDERR_FILENO);
        close(sys->old_stdout);
        close(sys->old_stderr);
        sys->old_stdout = sys->old_stderr = -1;
    }
    free(sys);
}
示例#7
0
std_logger *
std_logger_Open(const char *TAG)
{
    std_logger *sys = NULL;

    sys = (std_logger *)calloc(1, sizeof (std_logger));
    if (!sys)
        return NULL;

    sys->TAG = TAG;
    sys->stop_pipe[0] = sys->stop_pipe[1] =
                            sys->stdout_pipe[0] = sys->stdout_pipe[1] =
                                        sys->old_stdout = sys->old_stderr = -1;

    /* save the old stdout/stderr fd to restore it when logged is closed */
    sys->old_stdout = dup(STDOUT_FILENO);
    sys->old_stderr = dup(STDERR_FILENO);
    if (sys->old_stdout == -1 || sys->old_stderr == -1)
        goto bailout;

    /* duplicate stdout */
    if (pipe(sys->stdout_pipe) == -1)
        goto bailout;
    if (dup2(sys->stdout_pipe[1], STDOUT_FILENO) == -1)
        goto bailout;

    /* duplicate stderr */
    if (pipe(sys->stderr_pipe) == -1)
        goto bailout;
    if (dup2(sys->stderr_pipe[1], STDERR_FILENO) == -1)
        goto bailout;

    /* pipe to signal the thread to stop */
    if (pipe(sys->stop_pipe) == -1)
        goto bailout;

    if (pthread_create(&sys->thread, NULL, std_logger_Thread, sys))
    {
        ClosePipe(sys->stop_pipe);
        goto bailout;
    }

    return sys;
bailout:
    std_logger_Close(sys);
    return NULL;
}
示例#8
0
bool CRemoteCacheLink::EnsurePipeOpen()
{
	AutoLocker lock(m_critSec);

	if (InternalEnsurePipeOpen (m_hPipe, GetCachePipeName()))
	{
		// create an unnamed (=local) manual reset event for use in the overlapped structure
		if (m_hEvent)
			return true;

		m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (m_hEvent)
			return true;

		CTraceToOutputDebugString::Instance()(__FUNCTION__ ": CreateEvent failed");
		ClosePipe();
	}

	return false;
}
示例#9
0
int ESvnBase::ExecCommand(int Command, ExState &State) {
    switch (Command) {
        case ExChildClose:
            if (Running == 0 || PipeId == -1)
                break;
            ClosePipe ();
            {
                char s[30];

                sprintf(s, "[aborted, status=%d]", ReturnCode);
                AddLine(0, -1, s);
            }
            return ErOK;

        case ExActivateInOtherWindow:
            ShowLine(View->Next, Row);
            return ErOK;
    }
    return EList::ExecCommand(Command, State);
}
示例#10
0
文件: main.c 项目: abashkirtsev/Shell
int ProcessExternalCommand (struct data * d, struct comand * c)
{
	int status = COMMAND_OK;
	pid_t pid;
	int s = 0;
	pid = fork();
	if (pid == -1)
	{
		perror ("Crytical error: fork did not work");
		return RUN_ERROR;
	}
	if (pid == 0)
		ChildProcess (d, c);
	else
	{
		if (ClosePipe (&(d->in), &(d->out)))
			status = COMMAND_FAIL;
	}
	if (!d->bg)
	{
		if (d->pp)
		{
			++ d->i;
			AddToPipeList (pid, &(d->plist));
		}
		else
		{
			waitpid (pid, &s, 0);
			if (WIFEXITED (s))
			{
				if (WEXITSTATUS (s) != COMMAND_OK)
					status = COMMAND_FAIL;
			}
		}
	}
	return status;
}
示例#11
0
bool CCacheDlg::GetStatusFromRemoteCache(const CTGitPath& Path, bool bRecursive)
{
	if(!EnsurePipeOpen())
	{
		STARTUPINFO startup = { 0 };
		PROCESS_INFORMATION process = { 0 };
		startup.cb = sizeof(startup);

		CString sCachePath = L"TGitCache.exe";
		if (CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength() + 1), L"", nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process) == 0)
		{
			// It's not appropriate to do a message box here, because there may be hundreds of calls
			sCachePath.ReleaseBuffer();
			ATLTRACE("Failed to start cache\n");
			return false;
		}
		sCachePath.ReleaseBuffer();

		// Wait for the cache to open
		ULONGLONG endTime = GetTickCount64()+1000;
		while(!EnsurePipeOpen())
		{
			if((GetTickCount64() - endTime) > 0)
			{
				return false;
			}
		}
	}


	DWORD nBytesRead;
	TGITCacheRequest request;
	request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS;
	if(bRecursive)
	{
		request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS;
	}
	wcsncpy_s(request.path, Path.GetWinPath(), MAX_PATH);
	SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
	m_Overlapped.hEvent = m_hEvent;
	// Do the transaction in overlapped mode.
	// That way, if anything happens which might block this call
	// we still can get out of it. We NEVER MUST BLOCK THE SHELL!
	// A blocked shell is a very bad user impression, because users
	// who don't know why it's blocked might find the only solution
	// to such a problem is a reboot and therefore they might loose
	// valuable data.
	// Sure, it would be better to have no situations where the shell
	// even can get blocked, but the timeout of 5 seconds is long enough
	// so that users still recognize that something might be wrong and
	// report back to us so we can investigate further.

	TGITCacheResponse ReturnedStatus;
	BOOL fSuccess = TransactNamedPipe(m_hPipe,
		&request, sizeof(request),
		&ReturnedStatus, sizeof(ReturnedStatus),
		&nBytesRead, &m_Overlapped);

	if (!fSuccess)
	{
		if (GetLastError()!=ERROR_IO_PENDING)
		{
			ClosePipe();
			return false;
		}

		// TransactNamedPipe is working in an overlapped operation.
		// Wait for it to finish
		DWORD dwWait = WaitForSingleObject(m_hEvent, INFINITE);
		if (dwWait == WAIT_OBJECT_0)
		{
			fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE);
			return TRUE;
		}
		else
			fSuccess = FALSE;
	}

	ClosePipe();
	return false;
}
示例#12
0
bool CCacheDlg::EnsurePipeOpen()
{
	if(m_hPipe != INVALID_HANDLE_VALUE)
	{
		return true;
	}

	m_hPipe = CreateFile(
		GetCachePipeName(),   // pipe name
		GENERIC_READ |					// read and write access
		GENERIC_WRITE,
		0,								// no sharing
		nullptr,						// default security attributes
		OPEN_EXISTING,				// opens existing pipe
		FILE_FLAG_OVERLAPPED,			// default attributes
		nullptr);						// no template file

	if (m_hPipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY)
	{
		// TSVNCache is running but is busy connecting a different client.
		// Do not give up immediately but wait for a few milliseconds until
		// the server has created the next pipe instance
		if (WaitNamedPipe(GetCachePipeName(), 50))
		{
			m_hPipe = CreateFile(
				GetCachePipeName(),   // pipe name
				GENERIC_READ |					// read and write access
				GENERIC_WRITE,
				0,								// no sharing
				nullptr,						// default security attributes
				OPEN_EXISTING,				// opens existing pipe
				FILE_FLAG_OVERLAPPED,			// default attributes
				nullptr);						// no template file
		}
	}


	if (m_hPipe != INVALID_HANDLE_VALUE)
	{
		// The pipe connected; change to message-read mode.
		DWORD dwMode;

		dwMode = PIPE_READMODE_MESSAGE;
		if(!SetNamedPipeHandleState(
			m_hPipe,    // pipe handle
			&dwMode,  // new pipe mode
			nullptr,  // don't set maximum bytes
			nullptr)) // don't set maximum time
		{
			ATLTRACE("SetNamedPipeHandleState failed");
			CloseHandle(m_hPipe);
			m_hPipe = INVALID_HANDLE_VALUE;
			return false;
		}
		// create an unnamed (=local) manual reset event for use in the overlapped structure
		m_hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
		if (m_hEvent)
			return true;
		ATLTRACE("CreateEvent failed");
		ClosePipe();
		return false;
	}

	return false;
}
示例#13
0
CRemoteCacheLink::~CRemoteCacheLink(void)
{
	ClosePipe();
	CloseCommandPipe();
	m_critSec.Term();
}
示例#14
0
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive)
{
	if(!EnsurePipeOpen())
	{
		// We've failed to open the pipe - try and start the cache
		// but only if the last try to start the cache was a certain time
		// ago. If we just try over and over again without a small pause
		// in between, the explorer is rendered unusable!
		// Failing to start the cache can have different reasons: missing exe,
		// missing registry key, corrupt exe, ...
		if (((long)GetTickCount() - m_lastTimeout) < 0)
			return false;
		// if we're in protected mode, don't try to start the cache: since we're
		// here, we know we can't access it anyway and starting a new process will
		// trigger a warning dialog in IE7+ on Vista - we don't want that.
		if (GetProcessIntegrityLevel() < SECURITY_MANDATORY_MEDIUM_RID)
			return false;

		if (!RunTGitCacheProcess())
			return false;

		// Wait for the cache to open
		long endTime = (long)GetTickCount()+1000;
		while(!EnsurePipeOpen())
		{
			if(((long)GetTickCount() - endTime) > 0)
			{
				m_lastTimeout = (long)GetTickCount()+10000;
				return false;
			}
		}
		m_lastTimeout = (long)GetTickCount()+10000;
	}

	AutoLocker lock(m_critSec);

	DWORD nBytesRead;
	TGITCacheRequest request;
	request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS;
	if(bRecursive)
	{
		request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS;
	}
	wcsncpy_s(request.path, Path.GetWinPath(), _countof(request.path) - 1);
	SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
	m_Overlapped.hEvent = m_hEvent;
	// Do the transaction in overlapped mode.
	// That way, if anything happens which might block this call
	// we still can get out of it. We NEVER MUST BLOCK THE SHELL!
	// A blocked shell is a very bad user impression, because users
	// who don't know why it's blocked might find the only solution
	// to such a problem is a reboot and therefore they might loose
	// valuable data.
	// One particular situation where the shell could hang is when
	// the cache crashes and our crash report dialog comes up.
	// Sure, it would be better to have no situations where the shell
	// even can get blocked, but the timeout of 10 seconds is long enough
	// so that users still recognize that something might be wrong and
	// report back to us so we can investigate further.

	BOOL fSuccess = TransactNamedPipe(m_hPipe,
		&request, sizeof(request),
		pReturnedStatus, sizeof(*pReturnedStatus),
		&nBytesRead, &m_Overlapped);

	if (!fSuccess)
	{
		if (GetLastError()!=ERROR_IO_PENDING)
		{
			//OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n");
			ClosePipe();
			return false;
		}

		// TransactNamedPipe is working in an overlapped operation.
		// Wait for it to finish
		DWORD dwWait = WaitForSingleObject(m_hEvent, 10000);
		if (dwWait == WAIT_OBJECT_0)
		{
			fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE);
		}
		else
		{
			// the cache didn't respond!
			fSuccess = FALSE;
		}
	}

	if (fSuccess)
	{
		return true;
	}
	ClosePipe();
	return false;
}
示例#15
0
文件: Pipe.cpp 项目: dmead/sc2bot
Pipe::~Pipe()
{
    ClosePipe();
}
示例#16
0
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive)
{
	if(!EnsurePipeOpen())
	{
		// We've failed to open the pipe - try and start the cache
		// but only if the last try to start the cache was a certain time
		// ago. If we just try over and over again without a small pause
		// in between, the explorer is rendered unusable!
		// Failing to start the cache can have different reasons: missing exe,
		// missing registry key, corrupt exe, ...
		if (((long)GetTickCount() - m_lastTimeout) < 0)
			return false;
		STARTUPINFO startup;
		PROCESS_INFORMATION process;
		memset(&startup, 0, sizeof(startup));
		startup.cb = sizeof(startup);
		memset(&process, 0, sizeof(process));

		CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe");
#ifndef _WIN64
		typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
		LPFN_ISWOW64PROCESS fnIsWow64Process;
		fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

		if (NULL != fnIsWow64Process)
		{
			BOOL bIsWow64 = false;
			if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
			{
				bIsWow64 = false;
			}
			if (bIsWow64)
			{
				CRegString tgitinstalled64 = CRegString(_T("Software\\TortoiseGit\\CachePath"), _T(""), false, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY);
				if (!CString(tgitinstalled64).IsEmpty())
					sCachePath = tgitinstalled64;
			}
		}
		if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL))
		{
			ATLTRACE("Failed to start x64 cache\n");
			CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe");
			if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL))
			{
				// It's not appropriate to do a message box here, because there may be hundreds of calls
				ATLTRACE("Failed to start cache\n");
				return false;
			}
		}
#else
		if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL))
		{
			// It's not appropriate to do a message box here, because there may be hundreds of calls
			ATLTRACE("Failed to start cache\n");
			return false;
		}
#endif
		CloseHandle(process.hThread);
		CloseHandle(process.hProcess);
		sCachePath.ReleaseBuffer();

		// Wait for the cache to open
		long endTime = (long)GetTickCount()+1000;
		while(!EnsurePipeOpen())
		{
			if(((long)GetTickCount() - endTime) > 0)
			{
				m_lastTimeout = (long)GetTickCount()+10000;
				return false;
			}
		}
	}

	AutoLocker lock(m_critSec);

	DWORD nBytesRead;
	TGITCacheRequest request;
	request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS;
	if(bRecursive)
	{
		request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS;
	}
	wcsncpy_s(request.path, MAX_PATH+1, Path.GetWinPath(), MAX_PATH);
	SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
	m_Overlapped.hEvent = m_hEvent;
	// Do the transaction in overlapped mode.
	// That way, if anything happens which might block this call
	// we still can get out of it. We NEVER MUST BLOCK THE SHELL!
	// A blocked shell is a very bad user impression, because users
	// who don't know why it's blocked might find the only solution
	// to such a problem is a reboot and therefore they might lose
	// valuable data.
	// One particular situation where the shell could hang is when
	// the cache crashes and our crash report dialog comes up.
	// Sure, it would be better to have no situations where the shell
	// even can get blocked, but the timeout of 10 seconds is long enough
	// so that users still recognize that something might be wrong and
	// report back to us so we can investigate further.

	BOOL fSuccess = TransactNamedPipe(m_hPipe,
		&request, sizeof(request),
		pReturnedStatus, sizeof(*pReturnedStatus),
		&nBytesRead, &m_Overlapped);

	if (!fSuccess)
	{
		if (GetLastError()!=ERROR_IO_PENDING)
		{
			//OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n");
			ClosePipe();
			return false;
		}

		// TransactNamedPipe is working in an overlapped operation.
		// Wait for it to finish
		DWORD dwWait = WaitForSingleObject(m_hEvent, 10000);
		if (dwWait == WAIT_OBJECT_0)
		{
			fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE);
		}
		else
		{
			// the cache didn't respond!
			fSuccess = FALSE;
		}
	}

	if (fSuccess)
	{
		return true;
	}
	ClosePipe();
	return false;
}
示例#17
0
bool WhmShellProcess::run(WhmShellContext *sc)
{
	WhmShellCommand *c = command;
	bool result = true;	
	Token_t token = NULL;
#ifndef HTTP_PROXY
	if (runAsUser) {
		//创建运行身份令牌
		if (sc->vh==NULL) {
			sc->last_error = 128;
			return false;
		}
		token = sc->vh->createToken(result);
		if(!result){
			sc->last_error = 129;
			return false;
		}
	}
#endif
	//the commands stdout pipe
	PIPE_T big_stdout_pipe[2];
	if (!KPipeStream::create(big_stdout_pipe)) {
		if (token) {
			KVirtualHost::closeToken(token);
		}
		return false;
	}
	//the commands stdin pipe
	PIPE_T big_stdin_pipe[2];
	bool big_stdin_pipe_created = false;
	//init the std file
	PIPE_T hstdin = get_stdin(sc);
	if (hstdin==INVALIDE_PIPE && sc->in_buffer.getLen()>0) {
		//如果没有输入文件并且输入有数据。就要创建输入管道
		if (!KPipeStream::create(big_stdin_pipe)) {
			//关闭打开的big_stdout_pipe
			ClosePipe(big_stdout_pipe[0]);
			ClosePipe(big_stdout_pipe[1]);
			if (token) {
				KVirtualHost::closeToken(token);
			}
			return false;
		}
		big_stdin_pipe_created = true;
		hstdin = big_stdin_pipe[READ_PIPE];
	}
	PIPE_T hstdout = get_stdout(sc);
	PIPE_T hstderr = get_stderr(sc);
	PIPE_T in,out,err;
	err = hstderr;
	if (err==INVALIDE_PIPE) {
		err = big_stdout_pipe[WRITE_PIPE];
	}
	PIPE_T pp[2];
	for(int i=0;i<2;i++){
		pp[i] = INVALIDE_PIPE;
	}
	while (c) {
		char **arg = c->makeArgs(sc);
		KCmdEnv *env = c->makeEnv(sc);
		pid_t pid;
		kfinit(pid);
		//set in
		if (c==command) {
			in = hstdin;
		} else {
			assert(pp[READ_PIPE]!=INVALIDE_PIPE);
			in = pp[READ_PIPE];
			pp[READ_PIPE] = INVALIDE_PIPE;
			assert(pp[WRITE_PIPE]!=INVALIDE_PIPE);
			//close the out pipe
			ClosePipe(pp[WRITE_PIPE]);
			pp[WRITE_PIPE] = INVALIDE_PIPE;
		}
		//set out
		if (c->next) {
			//create a new pipe
			if (!KPipeStream::create(pp)) {
				if (c!=command) {
					ClosePipe(in);
				}
				break;
			}
			out = pp[WRITE_PIPE];
		} else {
			//if the command is last.
			//then set the out to big_pipe
			out = hstdout;
			if (out==INVALIDE_PIPE) {
				out = big_stdout_pipe[WRITE_PIPE];
			}
		}
		char *curdir2 = NULL;
		if (curdir) {
			curdir2 = sc->parseString(curdir);
		}
		result = createProcess(token,arg,env,curdir2,in,out,err,pid);
		if (curdir2) {
			free(curdir2);
		}
		if (c!=command) {
			//close the in pipe
			ClosePipe(in);
		}
		//free args
		for (int i=0;;i++) {
			if(arg[i]==NULL){
				break;
			}
			free(arg[i]);
		}
		delete[] arg;
		if (env) {
			delete env;
		}	
		sc->setLastPid(pid);
		if (!result) {
			sc->last_error = 127;
			break;
		}	
		c = c->next;
	}
	//关闭输入,输出父进程无用的管道端
	if (kflike(hstdin)) {
		ClosePipe(hstdin);
	}
	ClosePipe(big_stdout_pipe[WRITE_PIPE]);
	//处理输入
	if (big_stdin_pipe_created) {
		if (result) {
			//创建成功才写入数据
			buff *buf = sc->in_buffer.getHead();
			while (buf && buf->data) {
				if (write_pipe(big_stdin_pipe[WRITE_PIPE],buf->data,buf->used)!=buf->used) {
					break;
				}
				buf = buf->next;
			}
		}
		//清理输入数据和管道资源
		sc->in_buffer.destroy();
		ClosePipe(big_stdin_pipe[WRITE_PIPE]);
	}
	//处理输出
	if (result && (hstdout==INVALIDE_PIPE || hstderr==INVALIDE_PIPE)) {
		for (;;) {
			char buf[512];
			int len = read_pipe(big_stdout_pipe[READ_PIPE],buf,512);
			if (len<=0) {
				break;
			}
			sc->lock.Lock();
			if (sc->out_buffer.getLen() > 1048576) {
				//the out msg is too large.drop it.
				sc->lock.Unlock();
				fwrite(buf,1,len,stdout);
			} else {
				sc->out_buffer.write_all(buf,len);
				sc->lock.Unlock();
			}
			//fwrite(buf,1,len,stdout);	
		}
	}
	if (kflike(hstdout)) {
		ClosePipe(hstdout);
	}
	if (kflike(hstderr)) {
		ClosePipe(hstderr);
	}
	ClosePipe(big_stdout_pipe[READ_PIPE]);
	if (token) {
		KVirtualHost::closeToken(token);
	}
#ifdef _WIN32
	if (kflike(sc->last_pid)) {
		WaitForSingleObject(sc->last_pid,INFINITE);
	}
#endif
	return result;
}
示例#18
0
文件: Pipe.cpp 项目: dmead/sc2bot
void Pipe::CreatePipe(const String &PipeName)
{
    ClosePipe();
    const UINT PipeBufferSize = 100000;

    DWORD dwRes;
    PSID pEveryoneSID = NULL, pAdminSID = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[1];
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    SECURITY_ATTRIBUTES Attributes;
    HKEY hkSub = NULL;

    // Create a well-known SID for the Everyone group.
    BOOL Success = AllocateAndInitializeSid(&SIDAuthWorld, 1,
                                            SECURITY_WORLD_RID,
                                            0, 0, 0, 0, 0, 0, 0,
                                            &pEveryoneSID);
    Assert(Success != FALSE, "AllocateAndInitializeSid failed in Pipe::CreatePipe");

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow Everyone read access to the key.
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea[0].grfAccessPermissions = FILE_ALL_ACCESS;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance= NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(1, ea, NULL, &pACL);
    Assert(dwRes == ERROR_SUCCESS, "SetEntriesInAcl failed in Pipe::CreatePipe");

    // Initialize a security descriptor.  
    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
    Assert(pSD != NULL, "LocalAlloc failed in Pipe::CreatePipe");
    
    Success = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
    Assert(Success != FALSE, "InitializeSecurityDescriptor failed in Pipe::CreatePipe");
    
    // Add the ACL to the security descriptor. 
    Success = SetSecurityDescriptorDacl(pSD, 
                TRUE,     // bDaclPresent flag
                pACL, 
                FALSE);
    Assert(Success != FALSE, "SetSecurityDescriptorDacl failed in Pipe::CreatePipe");
    
    // Initialize a security attributes structure.
    Attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    Attributes.lpSecurityDescriptor = pSD;
    Attributes.bInheritHandle = FALSE;

    String FullPipeName = String("\\\\.\\pipe\\") + PipeName;
    _Handle = CreateNamedPipe( 
        FullPipeName.CString(),     // pipe name 
        PIPE_ACCESS_DUPLEX,         // read/write access 
        PIPE_TYPE_MESSAGE |         // message type pipe 
        PIPE_READMODE_MESSAGE |     // message-read mode 
        PIPE_WAIT,                  // blocking mode 
        PIPE_UNLIMITED_INSTANCES,   // max. instances  
        PipeBufferSize,             // output buffer size 
        PipeBufferSize,             // input buffer size 
        NMPWAIT_USE_DEFAULT_WAIT,   // client time-out 
        &Attributes);               // default security attribute
    Assert(_Handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed in Pipe::CreatePipe");

    //
    // Block until a connection comes in
    //
    BOOL Connected = (ConnectNamedPipe(_Handle, NULL) != 0);
    Assert(Connected != FALSE, "ConnectNamedPipe failed in Pipe::CreatePipe");
}