void SVNListBase::RefreshContent() { if (itsProcess != NULL) { JProcess* p = itsProcess; itsProcess = NULL; p->Kill(); delete p; DeleteLinks(); } else { itsSavedSelection->CleanOut(); JTableSelection& s = GetTableSelection(); JTableSelectionIterator iter(&s); JPoint cell; while (iter.Next(&cell)) { const JString* line = itsLineList->NthElement(cell.y); itsSavedSelection->InsertSorted(new JString(ExtractRelativePath(*line))); } } itsDisplayState = SaveDisplayState(); itsLineList->CleanOut(); int outFD, errFD; JError err = JNoError(); if ((GetDirector())->HasPath()) { err = JProcess::Create(&itsProcess, GetPath(), itsCmd, kJIgnoreConnection, NULL, kJCreatePipe, &outFD, kJCreatePipe, &errFD); } else // working with URL { err = JProcess::Create(&itsProcess, itsCmd, kJIgnoreConnection, NULL, kJCreatePipe, &outFD, kJCreatePipe, &errFD); } if (err.OK()) { itsProcess->ShouldDeleteWhenFinished(); ListenTo(itsProcess); (GetDirector())->RegisterActionProcess(this, itsProcess, itsRefreshRepoFlag, itsRefreshStatusFlag, itsReloadOpenFilesFlag); SetConnection(outFD, errFD); } else { err.ReportIfError(); } }
static UINT WINAPI ThreadJProcess(LPVOID lpParameter) { JProcess *pJProcess = (JProcess *)lpParameter; JMessage msg; msg.pBuffer = new byte[pJProcess->m_pJMsgManage->GetMsgLength()]; JRequest req; req.pBuffer = new byte[pJProcess->m_pJReqManage->GetReqLength()]; while (true) { //优先处理消息队列 if (pJProcess->PeekMessage(&msg, 0, 0, false)) { if (!pJProcess->GetMessage(&msg, 0, 0)) break; pJProcess->ProcEntry(pJProcess->GetState(), msg.dwEvent, msg.pBuffer, msg.nLength); continue; } //其次处理请求队列,从而控制请求的数量 if (pJProcess->PeekRequest(&req, 0, 0, false)) { if (!pJProcess->GetRequest(&req, 0, 0)) break; pJProcess->ProcEntry(pJProcess->GetState(), req.dwEvent, req.pBuffer, req.nLength); continue; } ::Sleep(10); } //收到EV_QUIT消息:退出消息循环,删除进程,杀死进程 delete msg.pBuffer; delete req.pBuffer; dword dwProcID = pJProcess->GetProcID(); g_pJProcManage->DelProcess(pJProcess); SAFE_DELETE(pJProcess); //删除退出标记 g_pJQuitManage->DelJQuit(dwProcID); return 0; }
JBoolean JGetSVNEntryType ( const JCharacter* url, JString* type, JString* error ) { type->Clear(); error->Clear(); JString cmd = "svn info --xml " + JPrepArgForExec(url); JProcess* p; int fromFD, errFD; JError err = JProcess::Create(&p, cmd, kJIgnoreConnection, NULL, kJCreatePipe, &fromFD, kJCreatePipe, &errFD); if (!err.OK()) { err.ReportIfError(); return kJFalse; } p->WaitUntilFinished(); if (p->SuccessfulFinish()) { xmlDoc* doc = xmlReadFd(fromFD, NULL, NULL, XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA); close(fromFD); if (doc != NULL) { xmlNode* root = xmlDocGetRootElement(doc); if (root != NULL && strcmp((char*) root->name, "info") == 0 && strcmp((char*) root->children->name, "entry") == 0) { *type = JGetXMLNodeAttr(root->children, "kind"); return kJTrue; } } } JReadAll(errFD, error, kJTrue); return kJFalse; }
JProcess *CreateJProcess(JProcessCreator *pCreator, dword dwProcID, byte byPriority, int nMsgLength, int nMsgSize, int nReqLength, int nReqSize) { JProcess *pJProcess = pCreator->CreateJProcess(dwProcID, byPriority); if (!pJProcess) return NULL; //添加进程队列 g_pJProcManage->AddProcess(pJProcess); //创建消息队列 if (!pJProcess->InitMsgManage(nMsgLength, nMsgSize)) return NULL; if (!pJProcess->InitReqManage(nReqLength, nReqSize)) return NULL; //初始化线程 if (!InitThreadJProcess(pJProcess)) return NULL; //延时重送事件 PostMessageWait(pJProcess->GetProcID(), EV_CREATE); return pJProcess; }
JBoolean JGetUserMountPointList ( JMountPointList* list, JMountState* state ) { JProcess* p; int outFD; const JError err = JProcess::Create(&p, kMountCmd, kJIgnoreConnection, NULL, kJCreatePipe, &outFD, kJIgnoreConnection, NULL); if (!err.OK()) { if (state != NULL) { jdelete state->mountCmdOutput; state->mountCmdOutput = NULL; } return kJFalse; } JString mountData; JReadAll(outFD, &mountData); p->WaitUntilFinished(); const JBoolean success = p->SuccessfulFinish(); jdelete p; p = NULL; if (!success) { if (state != NULL) { jdelete state->mountCmdOutput; state->mountCmdOutput = NULL; } return kJFalse; } if (state != NULL && state->mountCmdOutput != NULL && mountData == *(state->mountCmdOutput)) { return kJFalse; } list->CleanOut(); if (state != NULL && state->mountCmdOutput == NULL) { state->mountCmdOutput = jnew JString(mountData); assert( state->mountCmdOutput != NULL ); } else if (state != NULL) { *(state->mountCmdOutput) = mountData; } JIndexRange r; JArray<JIndexRange> matchList; JString options; ACE_stat stbuf; while (theLinePattern.MatchAfter(mountData, r, &matchList)) { r = matchList.GetFirstElement(); options = mountData.GetSubstring(matchList.GetElement(4)); if (options.Contains("nobrowse")) { continue; } JString* path = jnew JString(mountData.GetSubstring(matchList.GetElement(3))); assert( path != NULL ); JString* devicePath = jnew JString(mountData.GetSubstring(matchList.GetElement(2))); assert( devicePath != NULL ); const JMountType type = JGetUserMountPointType(*path, *devicePath, ""); if (type == kJUnknownMountType || ACE_OS::stat(*path, &stbuf) != 0) { jdelete path; jdelete devicePath; continue; } JFileSystemType fsType = kOtherFSType; if (options.Contains("msdos")) { fsType = kVFATType; } list->AppendElement(JMountPoint(path, type, stbuf.st_dev, devicePath, fsType)); } return kJTrue; }
JError JExecute ( const JCharacter* argv[], const JSize size, pid_t* childPID, const JExecuteAction toAction, int* toFD, const JExecuteAction origFromAction, int* fromFD, const JExecuteAction errAction, int* errFD ) { assert( size > sizeof(JCharacter*) ); assert( argv[ (size/sizeof(JCharacter*)) - 1 ] == NULL ); const JExecuteAction fromAction = (origFromAction == kJForceNonblockingPipe ? kJCreatePipe : origFromAction); assert( toAction != kJTossOutput && toAction != kJAttachToFromFD && toAction != kJForceNonblockingPipe ); assert( fromAction != kJAttachToFromFD ); assert( errAction != kJForceNonblockingPipe ); assert( (toAction != kJCreatePipe && toAction != kJAttachToFD) || toFD != NULL ); assert( (fromAction != kJCreatePipe && fromAction != kJAttachToFD) || fromFD != NULL ); assert( (errAction != kJCreatePipe && errAction != kJAttachToFD) || errFD != NULL ); JString progName; if (!JProgramAvailable(argv[0], &progName)) { return JProgramNotAvailable(argv[0]); } argv[0] = progName.GetCString(); int fd[3][2]; if (toAction == kJCreatePipe) { const JError err = JCreatePipe(fd[0]); if (!err.OK()) { return err; } } if (fromAction == kJCreatePipe) { const JError err = JCreatePipe(fd[1]); if (!err.OK()) { if (toAction == kJCreatePipe) { close(fd[0][0]); close(fd[0][1]); } return err; } } if (errAction == kJCreatePipe) { const JError err = JCreatePipe(fd[2]); if (!err.OK()) { if (toAction == kJCreatePipe) { close(fd[0][0]); close(fd[0][1]); } if (fromAction == kJCreatePipe) { close(fd[1][0]); close(fd[1][1]); } return err; } } pid_t pid; const JError err = JThisProcess::Fork(&pid); if (!err.OK()) { if (toAction == kJCreatePipe) { close(fd[0][0]); close(fd[0][1]); } if (fromAction == kJCreatePipe) { close(fd[1][0]); close(fd[1][1]); } if (errAction == kJCreatePipe) { close(fd[2][0]); close(fd[2][1]); } return err; } // child else if (pid == 0) { const int stdinFD = fileno(stdin); if (toAction == kJCreatePipe) { dup2(fd[0][0], stdinFD); close(fd[0][0]); close(fd[0][1]); } else if (toAction == kJAttachToFD) { dup2(*toFD, stdinFD); close(*toFD); } const int stdoutFD = fileno(stdout); if (fromAction == kJCreatePipe) { dup2(fd[1][1], stdoutFD); close(fd[1][0]); close(fd[1][1]); } else if (fromAction == kJAttachToFD) { dup2(*fromFD, stdoutFD); close(*fromFD); } else if (fromAction == kJTossOutput) { FILE* nullFile = fopen("/dev/null", "a"); int nullfd = fileno(nullFile); dup2(nullfd, stdoutFD); fclose(nullFile); } const int stderrFD = fileno(stderr); if (errAction == kJCreatePipe) { dup2(fd[2][1], stderrFD); close(fd[2][0]); close(fd[2][1]); } else if (errAction == kJAttachToFD) { dup2(*errFD, stderrFD); close(*errFD); } else if (errAction == kJTossOutput) { FILE* nullFile = fopen("/dev/null", "a"); int nullfd = fileno(nullFile); dup2(nullfd, stderrFD); fclose(nullFile); } else if (errAction == kJAttachToFromFD && fromAction != kJIgnoreConnection) { dup2(stdoutFD, stderrFD); } ACE_OS::execvp(argv[0], const_cast<char* const*>(argv)); cerr << "Unable to run program \"" << argv[0] << '"' << endl; cerr << endl; cerr << "JExecute()::execvp() failed" << endl; cerr << "Errno value: " << jerrno() << endl; JThisProcess::Exit(1); return JNoError(); } // parent else { if (origFromAction == kJForceNonblockingPipe) { pid_t pid2; const JError err2 = JThisProcess::Fork(&pid2); if (err2.OK() && pid2 == 0) { for (int i=0; i<150; i++) { JWait(0.1); int value = fcntl(fd[1][1], F_GETFL, 0); if (value & O_NONBLOCK) { cerr << "turning off nonblocking for cout: " << value << endl; fcntl(fd[1][1], F_SETFL, value & (~ O_NONBLOCK)); } } JThisProcess::Exit(0); return JNoError(); } JProcess* p = new JProcess(pid2); p->KillAtExit(kJTrue); } if (toAction == kJCreatePipe) { close(fd[0][0]); *toFD = fd[0][1]; } if (fromAction == kJCreatePipe) { close(fd[1][1]); *fromFD = fd[1][0]; } if (errAction == kJCreatePipe) { close(fd[2][1]); *errFD = fd[2][0]; } if (childPID == NULL) { return JWaitForChild(pid); } else { *childPID = pid; return JNoError(); } } }
JError JRemoveVCS ( const JCharacter* fullName, const JBoolean sync, JProcess** returnP ) { if (returnP != NULL) { *returnP = NULL; } if (!JNameUsed(fullName)) { return JDirEntryDoesNotExist(fullName); } JString path, name; JSplitPathAndName(fullName, &path, &name); const JString origPath = JGetCurrentDirectory(); if (JChangeDirectory(path) != kJNoError) { return JAccessDenied(path); } JVCSType type = JGetVCSType(path); JError err = JNoError(); JBoolean tryPlain = kJFalse; JString cmd; JProcess* p = NULL; if (type == kJSVNType || type == kJGitType) { const JCharacter *binary = NULL; if (type == kJSVNType) { binary = "svn rm --force "; } else if (type == kJGitType) { binary = "git rm -rf "; } cmd = binary; cmd += JPrepArgForExec(name); err = JProcess::Create(&p, cmd); if (err.OK()) { p->WaitUntilFinished(); } if (p != NULL && !p->SuccessfulFinish()) { err = JAccessDenied(fullName); tryPlain = kJTrue; } } else if (type == kJUnknownVCSType) { tryPlain = kJTrue; } else { err = JUnsupportedVCS(fullName); } if (tryPlain && JKillDirectory(fullName, sync, returnP)) { err = JNoError(); } else if (tryPlain) { err = JAccessDenied(fullName); } delete p; JChangeDirectory(origPath); return err; }
JError JRenameVCS ( const JCharacter* oldFullName, const JCharacter* newFullName ) { if (!JNameUsed(oldFullName)) { return JDirEntryDoesNotExist(oldFullName); } JString oldPath, newPath, name; JSplitPathAndName(newFullName, &newPath, &name); JSplitPathAndName(oldFullName, &oldPath, &name); // must be second const JString origPath = JGetCurrentDirectory(); if (JChangeDirectory(oldPath) != kJNoError) { return JAccessDenied(oldPath); } JVCSType type1 = JGetVCSType(oldPath); JVCSType type2 = JGetVCSType(newPath); JError err = JNoError(); JBoolean tryPlain = kJFalse; JString cmd; JProcess* p = NULL; if (type1 != type2) { tryPlain = kJTrue; } else if (type1 == kJSVNType || type1 == kJGitType) { if (type1 == kJSVNType) { cmd = "svn mv --force "; cmd += JPrepArgForExec(oldFullName); cmd += " "; cmd += JPrepArgForExec(newFullName); } else if (type1 == kJGitType) { cmd = "git mv -f "; cmd += JPrepArgForExec(name); cmd += " "; cmd += JPrepArgForExec(newFullName); } err = JProcess::Create(&p, cmd); if (err.OK()) { p->WaitUntilFinished(); } if (p != NULL && !p->SuccessfulFinish()) { err = JAccessDenied(oldFullName, newFullName); tryPlain = kJTrue; } } else if (type1 == kJUnknownVCSType) { tryPlain = kJTrue; } else { err = JUnsupportedVCS(oldFullName); } if (tryPlain && JProgramAvailable("mv")) { cmd = "mv "; cmd += JPrepArgForExec(oldFullName); cmd += " "; cmd += JPrepArgForExec(newFullName); JSimpleProcess* p1; err = JSimpleProcess::Create(&p1, cmd); p = p1; if (err.OK()) { p->WaitUntilFinished(); if (!p->SuccessfulFinish()) { err = JAccessDenied(oldFullName, newFullName); } } } else if (tryPlain) { err = JRenameDirEntry(oldFullName, newFullName); } delete p; JChangeDirectory(origPath); return err; }