JBoolean JProgramAvailable ( const JCharacter* programName ) { JString s; return JProgramAvailable(programName, &s); }
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 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; }