Example #1
0
bool Process::failed()
// ----------------------------------------------------------------------------
//   Return true if the process crashed or returned a non-zero value
// ----------------------------------------------------------------------------
{
  return (exitStatus() != QProcess::NormalExit) || exitCode();
}
Example #2
0
bool Process::done(text *errors, text *output)
// ----------------------------------------------------------------------------
//    Return true if the process was successful
// ----------------------------------------------------------------------------
{
    bool ok = true;

    // Flush streambuf
    if (pbase())
        if (sync())
            ok = false;
    delete[] pbase();
    setp(NULL, NULL);

    // Close QProcess
    closeWriteChannel();
    if (state() != NotRunning)
        if (!waitForFinished())
            ok = false;

    int rc = exitCode();
    if (rc)
        ok = false;

    if (output)
        *output = +out;
    if (errors)
        *errors = +err;

    return ok;
}
Example #3
0
void Task::runCloseAllVolumeTask()
{
	m_table->setEnabled( false ) ;
	sleep( 1 ) ; // for ui effect

	int volumeCount = m_table->rowCount() ;

	if( volumeCount > 0 ){

		QVector< QTableWidgetItem * > tableItems( volumeCount ) ;
		QTableWidgetItem ** it = tableItems.data() ;

		for( int i = 0 ; i < volumeCount ; i++ ){
			*( it + i ) = m_table->item( i,0 ) ;
		}

		for( QTableWidgetItem * it : tableItems ){
			QString device = it->text().replace( "\"","\"\"\"" ) ;
			auto r = utility::Task( QString( "%1 -q -d \"%2\"" ).arg( ZULUCRYPTzuluCrypt ).arg( device ) ) ;
			emit taskResult( it,r.exitCode() ) ;
			sleep( 1 ) ; // for ui effect
		}
	}

	m_table->setEnabled( true ) ;
}
Example #4
0
  virtual ptr<Process> start() override {
    auto builder = _connector->processBuilder();

    // Prepare the OAR command

    if (detach) throw illegal_argument_error("Cannot run OAR undetached");

    auto pushstream = [&] (Redirect & r)  {
      switch (r.type) {
        case Redirection::INHERIT:
        case Redirection::PIPE:
          throw illegal_argument_error("Cannot run OAR undetached");

        case Redirection::NONE:
          builder->command.push_back("/dev/null");
          break;

        case Redirection::FILE:
          builder->command.push_back(r.path);
          break;
      }

    };

    auto process = builder->start();
    builder->command.push_back("oarsub");
    builder->command.push_back("-O");
    pushstream(builder->stdout);
    builder->command.push_back("-E");
    pushstream(builder->stderr);
    builder->detach = false;


    std::ostringstream oss;
    bool first;
    for(auto c: command) {
      if (first) first = false;
      else oss << " ";
      oss << "\"" << ShScriptBuilder::protect_quoted(c) << "\"";
    }
    builder->command.push_back(oss.str());


    // Execute it
    EnvMatcher matcher("\nOAR_JOB_ID=");
    builder->stdout = Redirect::pipe([&](const char * bytes, size_t n) {
      matcher.process(bytes, n);
    });
    int code = process->exitCode();
    
    if (code != 0) {
      throw exception(fmt::format("Could not launch OAR process {}", code));
    }

    if (matcher.value.empty())
      throw exception("Could not get the OAR job ID");

    return mkptr<OARProcess>(matcher.value, _connector);

  }
Example #5
0
 bool TempMemory::isThreadDead() const
 {
     HANDLE threadHandle(OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId_));
     if(threadHandle) {
         DWORD exitCode(0);
         BOOL result = GetExitCodeThread(threadHandle, &exitCode);
         CloseHandle(threadHandle);
         if(result != 0) {
             if(exitCode == STILL_ACTIVE) {
                 // still running
                 return false;
             }
             else {
                 // it's gone
                 return true;
             }
         }
         else {
             // fail safe and don't delete in this case
             return false;
         }
     }
     else {
         // fail safe and don't delete in this case
         return false;
     }
 }
Example #6
0
QString IpProcess::executeSynchronous(const QString &program, const QStringList &arguments)
{
    QString empty("");
    QString result("");

    printCmdLine(program, arguments);

    if (arguments.count() > 0)
    {
        start(program, arguments);
    }
    else
    {
        start(program);
    }

    if (! waitForStarted())
        return empty;

    closeWriteChannel();

    int secondsToWait = 30;
    if (! waitForFinished(secondsToWait * 1000))
        return empty;

    // exit code of zero means command completed ok
    // and that output is from stdout - error output is on stderrs
    if ( (exitCode() == 0) && (errStr.isEmpty()) )
    {
        result = QString(QString(readAllStandardOutput()));
    }
    else
    {
        result = QString(QString(readAllStandardError()));
    }

    if (result.isEmpty())
    {
        // result = parseErrorCode();
    }

    // Send the result of executing the command
    emit cmdOutput(program, arguments, exitCode(), result);

    return QString(result);
}
Example #7
0
void Task::runExeTask()
{
	auto r   = utility::Task( m_exe ) ;
	m_status = r.exitCode() ;
	m_output = r.output() ;
	if( m_action == Task::closeVolumeTask ){
		sleep( 1 ) ; // for UI effect
	}
}
Example #8
0
void KJavaProcess::slotExited()
{
    int status = -1;
    if ( exitStatus() == NormalExit ) {
     status = exitCode();
    }
    kDebug(6100) << "jvm exited with status " << status; 
    emit exited(status);
}
Example #9
0
int KProcess::execute(int msecs)
{
    start();
    if (!waitForFinished(msecs)) {
        kill();
        waitForFinished(-1);
        return -2;
    }
    return (exitStatus() == QProcess::NormalExit) ? exitCode() : -1;
}
Example #10
0
void ScProcess::postQuitNotification()
{
    QString message;
    switch (exitStatus()) {
    case QProcess::CrashExit:
        message = tr("Interpreter has crashed or stopped forcefully. [Exit code: %1]\n").arg(exitCode());
        break;
    default:
        message = tr("Interpreter has quit. [Exit code: %1]\n").arg(exitCode());
    }
    emit scPost(message);
}
Example #11
0
std::string RunResult::str() const {
  if (exitCode() != 0)
    return "<failed>";

  if (returnValues_.empty())
    return "<nothing>";

  std::ostringstream ret;
  for (RunReturn::const_iterator it = returnValues_.begin();
      it != returnValues_.end(); ++it)
    ret << it->first << " =\t" << it->second << '\n';

  return ret.str();
}
Example #12
0
//
// Perform the canonical last rites for a formerly alive child.
// Requires master lock held throughout.
//
void Child::bury(int status)
{
	assert(mState == alive);
	mState = dead;
	mStatus = status;
	mChildren().erase(mPid);
#if !defined(NDEBUG)
	if (bySignal())
		secdebug("unixchild", "%p (pid %d) died by signal %d%s",
			this, mPid, exitSignal(),
			coreDumped() ? " and dumped core" : "");
	else
		secdebug("unixchild", "%p (pid %d) died by exit(%d)",
			this, mPid, exitCode());
#endif //NDEBUG
}
Example #13
0
void
BaseShadow::logRequeueEvent( const char* reason )
{
	struct rusage run_remote_rusage;
	memset( &run_remote_rusage, 0, sizeof(struct rusage) );

	run_remote_rusage = getRUsage();

	int exit_reason = getExitReason();

	JobEvictedEvent event;

	event.terminate_and_requeued = true;

	if( exitedBySignal() ) {
		event.normal = false;
		event.signal_number = exitSignal();
	} else {
		event.normal = true;
		event.return_value = exitCode();
	}
			
	if( exit_reason == JOB_COREDUMPED ) {
		event.setCoreFile( core_file_name );
	}

	if( reason ) {
		event.setReason( reason );
	}

		// TODO: fill in local rusage
		// event.run_local_rusage = r;
	event.run_remote_rusage = run_remote_rusage;

		/* we want to log the events from the perspective 
		   of the user job, so if the shadow *sent* the 
		   bytes, then that means the user job *received* 
		   the bytes */
	event.recvd_bytes = bytesSent();
	event.sent_bytes = bytesReceived();
	
	if (!uLog.writeEvent (&event,jobAd)) {
		dprintf( D_ALWAYS, "Unable to log ULOG_JOB_EVICTED "
				 "(and requeued) event\n" );
	}
}
Example #14
0
int main(int argc, char** argv)
{
    RemoveCrashDump removeCrashDump;
#ifdef OS_Darwin
    struct rlimit rlp;
    if (getrlimit(RLIMIT_NOFILE, &rlp) == 0) {
        if (rlp.rlim_cur < 1000) {
            rlp.rlim_cur = 1000;
            setrlimit(RLIMIT_NOFILE, &rlp);
        }
    }
#endif

    Rct::findExecutablePath(*argv);

    bool daemon = false;
    Server::Options serverOpts;
    const char * runtimeDir = getenv("XDG_RUNTIME_DIR");
    if (runtimeDir == NULL) {
        serverOpts.socketFile = String::format<128>("%s.rdm", Path::home().constData());
    } else {
        serverOpts.socketFile = String::format<1024>("%s/rdm.socket", runtimeDir);
    }
    serverOpts.jobCount = std::max(2, ThreadPool::idealThreadCount());
    serverOpts.headerErrorJobCount = -1;
    serverOpts.rpVisitFileTimeout = DEFAULT_RP_VISITFILE_TIMEOUT;
    serverOpts.rpIndexDataMessageTimeout = DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT;
    serverOpts.rpConnectTimeout = DEFAULT_RP_CONNECT_TIMEOUT;
    serverOpts.rpConnectAttempts = DEFAULT_RP_CONNECT_ATTEMPTS;
    serverOpts.maxFileMapScopeCacheSize = DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE;
    serverOpts.errorLimit = DEFAULT_ERROR_LIMIT;
    serverOpts.rpNiceValue = INT_MIN;
    serverOpts.options = Server::Wall|Server::SpellChecking;
    serverOpts.maxCrashCount = DEFAULT_MAX_CRASH_COUNT;
    serverOpts.completionCacheSize = DEFAULT_COMPLETION_CACHE_SIZE;
    serverOpts.maxIncludeCompletionDepth = DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH;
    serverOpts.rp = defaultRP();
    strcpy(crashDumpFilePath, "crash.dump");
#ifdef FILEMANAGER_OPT_IN
    serverOpts.options |= Server::NoFileManagerWatch;
#endif
    // #ifndef NDEBUG
    //     serverOpts.options |= Server::SuspendRPOnCrash;
    // #endif
    serverOpts.dataDir = String::format<128>("%s.rtags", Path::home().constData());
    if (!serverOpts.dataDir.exists()) {
         const char * dataDir = getenv("XDG_CACHE_HOME");
         serverOpts.dataDir = dataDir ? dataDir : Path::home() + ".cache";
         serverOpts.dataDir += "/rtags/";
         serverOpts.dataDir.mkdir(Path::Recursive);
    }
    Path logFile;
    Flags<LogFlag> logFlags = DontRotate|LogStderr;
    LogLevel logLevel(LogLevel::Error);
    LogLevel logFileLogLevel(LogLevel::Error);
    bool sigHandler = true;
    assert(Path::home().endsWith('/'));
    int inactivityTimeout = 0;

    const std::initializer_list<CommandLineParser::Option<OptionType> > opts = {
        { None, 0, 0, CommandLineParser::NoValue, "Options:" },
        { Help, "help", 'h', CommandLineParser::NoValue, "Display this page." },
        { Version, "version", 0, CommandLineParser::NoValue, "Display version." },
        { IncludePath, "include-path", 'I', CommandLineParser::Required, "Add additional include path to clang." },
        { Isystem, "isystem", 's', CommandLineParser::Required, "Add additional system include path to clang." },
        { Define, "define", 'D', CommandLineParser::Required, "Add additional define directive to clang." },
        { DefaultArgument, "default-argument", 0, CommandLineParser::Required, "Add additional argument to clang." },
        { LogFile, "log-file", 'L', CommandLineParser::Required, "Log to this file." },
        { CrashDumpFile, "crash-dump-file", 0, CommandLineParser::Required, "File to dump crash log to (default is <datadir>/crash.dump)." },
        { SetEnv, "setenv", 'e', CommandLineParser::Required, "Set this environment variable (--setenv \"foobar=1\")." },
        { NoWall, "no-Wall", 'W', CommandLineParser::NoValue, "Don't use -Wall." },
        { Weverything, "Weverything", 'u', CommandLineParser::NoValue, "Use -Weverything." },
        { Verbose, "verbose", 'v', CommandLineParser::NoValue, "Change verbosity, multiple -v's are allowed." },
        { JobCount, "job-count", 'j', CommandLineParser::Required, String::format("Spawn this many concurrent processes for indexing (default %d).",
                                                                                  std::max(2, ThreadPool::idealThreadCount())) },
        { HeaderErrorJobCount, "header-error-job-count", 'H', CommandLineParser::Required, "Allow this many concurrent header error jobs (default std::max(1, --job-count / 2))." },
        { Test, "test", 't', CommandLineParser::Required, "Run this test." },
        { TestTimeout, "test-timeout", 'z', CommandLineParser::Required, "Timeout for test to complete." },
        { CleanSlate, "clean-slate", 'C', CommandLineParser::NoValue, "Clear out all data." },
        { DisableSigHandler, "disable-sighandler", 'x', CommandLineParser::NoValue, "Disable signal handler to dump stack for crashes." },
        { Silent, "silent", 'S', CommandLineParser::NoValue, "No logging to stdout/stderr." },
        { ExcludeFilter, "exclude-filter", 'X', CommandLineParser::Required, "Files to exclude from rdm, default \"" DEFAULT_EXCLUDEFILTER "\"." },
        { SocketFile, "socket-file", 'n', CommandLineParser::Required, "Use this file for the server socket (default ~/.rdm)." },
        { DataDir, "data-dir", 'd', CommandLineParser::Required, "Use this directory to store persistent data (default $XDG_CACHE_HOME/rtags otherwise ~/.cache/rtags)." },
        { IgnorePrintfFixits, "ignore-printf-fixits", 'F', CommandLineParser::NoValue, "Disregard any clang fixit that looks like it's trying to fix format for printf and friends." },
        { ErrorLimit, "error-limit", 'f', CommandLineParser::Required, "Set error limit to argument (-ferror-limit={arg} (default " STR(DEFAULT_ERROR_LIMIT) ")." },
        { BlockArgument, "block-argument", 'G', CommandLineParser::Required, "Block this argument from being passed to clang. E.g. rdm --block-argument -fno-inline" },
        { NoSpellChecking, "no-spell-checking", 'l', CommandLineParser::NoValue, "Don't pass -fspell-checking." },
        { LargeByValueCopy, "large-by-value-copy", 'r', CommandLineParser::Required, "Use -Wlarge-by-value-copy=[arg] when invoking clang." },
        { AllowMultipleSources, "allow-multiple-sources", 'm', CommandLineParser::NoValue, "Don't merge source files added with -c." },
        { NoStartupProject, "no-startup-project", 'o', CommandLineParser::NoValue, "Don't restore the last current project on startup." },
        { NoNoUnknownWarningsOption, "no-no-unknown-warnings-option", 'Y', CommandLineParser::NoValue, "Don't pass -Wno-unknown-warning-option." },
        { IgnoreCompiler, "ignore-compiler", 'b', CommandLineParser::Required, "Ignore this compiler." },
        { CompilerWrappers, "compiler-wrappers", 0, CommandLineParser::Required, "Consider these filenames compiler wrappers (split on ;), default " DEFAULT_COMPILER_WRAPPERS "\"." },
        { WatchSystemPaths, "watch-system-paths", 'w', CommandLineParser::NoValue, "Watch system paths for changes." },
        { RpVisitFileTimeout, "rp-visit-file-timeout", 'Z', CommandLineParser::Required, "Timeout for rp visitfile commands in ms (0 means no timeout) (default " STR(DEFAULT_RP_VISITFILE_TIMEOUT) ")." },
        { RpIndexerMessageTimeout, "rp-indexer-message-timeout", 'T', CommandLineParser::Required, "Timeout for rp indexer-message in ms (0 means no timeout) (default " STR(DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT) ")." },
        { RpConnectTimeout, "rp-connect-timeout", 'O', CommandLineParser::Required, "Timeout for connection from rp to rdm in ms (0 means no timeout) (default " STR(DEFAULT_RP_CONNECT_TIMEOUT) ")." },
        { RpConnectAttempts, "rp-connect-attempts", 0, CommandLineParser::Required, "Number of times rp attempts to connect to rdm before giving up. (default " STR(DEFAULT_RP_CONNECT_ATTEMPTS) ")." },
        { RpNiceValue, "rp-nice-value", 'a', CommandLineParser::Required, "Nice value to use for rp (nice(2)) (default is no nicing)." },
        { SuspendRpOnCrash, "suspend-rp-on-crash", 'q', CommandLineParser::NoValue, "Suspend rp in SIGSEGV handler (default " DEFAULT_SUSPEND_RP ")." },
        { RpLogToSyslog, "rp-log-to-syslog", 0, CommandLineParser::NoValue, "Make rp log to syslog." },
        { StartSuspended, "start-suspended", 'Q', CommandLineParser::NoValue, "Start out suspended (no reindexing enabled)." },
        { SeparateDebugAndRelease, "separate-debug-and-release", 'E', CommandLineParser::NoValue, "Normally rdm doesn't consider release and debug as different builds. Pass this if you want it to." },
        { Separate32BitAnd64Bit, "separate-32-bit-and-64-bit", 0, CommandLineParser::NoValue, "Normally rdm doesn't consider -m32 and -m64 as different builds. Pass this if you want it to." },
        { SourceIgnoreIncludePathDifferencesInUsr, "ignore-include-path-differences-in-usr", 0, CommandLineParser::NoValue, "Don't consider sources that only differ in includepaths within /usr (not including /usr/home/) as different builds." },
        { MaxCrashCount, "max-crash-count", 'K', CommandLineParser::Required, "Max number of crashes before giving up a sourcefile (default " STR(DEFAULT_MAX_CRASH_COUNT) ")." },
        { CompletionCacheSize, "completion-cache-size", 'i', CommandLineParser::Required, "Number of translation units to cache (default " STR(DEFAULT_COMPLETION_CACHE_SIZE) ")." },
        { CompletionNoFilter, "completion-no-filter", 0, CommandLineParser::NoValue, "Don't filter private members and destructors from completions." },
        { CompletionLogs, "completion-logs", 0, CommandLineParser::NoValue, "Log more info about completions." },
        { MaxIncludeCompletionDepth, "max-include-completion-depth", 0, CommandLineParser::Required, "Max recursion depth for header completion (default " STR(DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH) ")." },
        { AllowWpedantic, "allow-Wpedantic", 'P', CommandLineParser::NoValue, "Don't strip out -Wpedantic. This can cause problems in certain projects." },
        { AllowWErrorAndWFatalErrors, "allow-Werror", 0, CommandLineParser::NoValue, "Don't strip out -Werror and -Wfatal-errors. By default these are stripped out. " },
        { EnableCompilerManager, "enable-compiler-manager", 'R', CommandLineParser::NoValue, "Query compilers for their actual include paths instead of letting clang use its own." },
        { EnableNDEBUG, "enable-NDEBUG", 'g', CommandLineParser::NoValue, "Don't remove -DNDEBUG from compile lines." },
        { Progress, "progress", 'p', CommandLineParser::NoValue, "Report compilation progress in diagnostics output." },
        { MaxFileMapCacheSize, "max-file-map-cache-size", 'y', CommandLineParser::Required, "Max files to cache per query (Should not exceed maximum number of open file descriptors allowed per process) (default " STR(DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE) ")." },
#ifdef FILEMANAGER_OPT_IN
        { FileManagerWatch, "filemanager-watch", 'M', CommandLineParser::NoValue, "Use a file system watcher for filemanager." },
#else
        { NoFileManagerWatch, "no-filemanager-watch", 'M', CommandLineParser::NoValue, "Don't use a file system watcher for filemanager." },
#endif
        { NoFileManager, "no-filemanager", 0, CommandLineParser::NoValue, "Don't scan project directory for files. (rc -P won't work)." },
        { NoFileLock, "no-file-lock", 0, CommandLineParser::NoValue, "Disable file locking. Not entirely safe but might improve performance on certain systems." },
        { PchEnabled, "pch-enabled", 0, CommandLineParser::NoValue, "Enable PCH (experimental)." },
        { NoFilesystemWatcher, "no-filesystem-watcher", 'B', CommandLineParser::NoValue, "Disable file system watching altogether. Reindexing has to be triggered manually." },
        { ArgTransform, "arg-transform", 'V', CommandLineParser::Required, "Use arg to transform arguments. [arg] should be executable with (execv(3))." },
        { NoComments, "no-comments", 0, CommandLineParser::NoValue, "Don't parse/store doxygen comments." },
#ifdef RTAGS_HAS_LAUNCHD
        { Launchd, "launchd", 0, CommandLineParser::NoValue, "Run as a launchd job (use launchd API to retrieve socket opened by launchd on rdm's behalf)." },
#endif
        { InactivityTimeout, "inactivity-timeout", 0, CommandLineParser::Required, "Time in seconds after which rdm will quit if there's been no activity (N.B., once rdm has quit, something will need to re-run it!)." },
        { Daemon, "daemon", 0, CommandLineParser::NoValue, "Run as daemon (detach from terminal)." },
        { LogFileLogLevel, "log-file-log-level", 0, CommandLineParser::Required, "Log level for log file (default is error), options are: error, warning, debug or verbose-debug." },
        { WatchSourcesOnly, "watch-sources-only", 0, CommandLineParser::NoValue, "Only watch source files (not dependencies)." },
        { DebugLocations, "debug-locations", 0, CommandLineParser::NoValue, "Set debug locations." },
        { ValidateFileMaps, "validate-file-maps", 0, CommandLineParser::NoValue, "Spend some time validating project data on startup." },
        { TcpPort, "tcp-port", 0, CommandLineParser::Required, "Listen on this tcp socket (default none)." },
        { RpPath, "rp-path", 0, CommandLineParser::Required, String::format<256>("Path to rp (default %s).", defaultRP().constData()) },
        { LogTimestamp, "log-timestamp", 0, CommandLineParser::NoValue, "Add timestamp to logs." },
        { LogFlushOption, "log-flush", 0, CommandLineParser::NoValue, "Flush stderr/stdout after each log." },
        { SandboxRoot, "sandbox-root",  0, CommandLineParser::Required, "Create index using relative paths by stripping dir (enables copying of tag index db files without need to reindex)." },
        { PollTimer, "poll-timer", 0, CommandLineParser::Required, "Poll the database of the current project every <arg> seconds. " },
        { NoRealPath, "no-realpath", 0, CommandLineParser::NoValue, "Don't use realpath(3) for files" },
        { Noop, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." },
        { Noop, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." }
    };

    std::function<CommandLineParser::ParseStatus(OptionType type, String &&value, size_t &idx, const List<String> &args)> cb;
    cb = [&](OptionType type, String &&value, size_t &, const List<String> &) -> CommandLineParser::ParseStatus {
        switch (type) {
        case None:
        case Noop:
        break;
        case Help: {
            CommandLineParser::help(stdout, Rct::executablePath().fileName(), opts);
            return { String(), CommandLineParser::Parse_Ok }; }
        case Version: {
            fprintf(stdout, "%s\n", RTags::versionString().constData());
            return { String(), CommandLineParser::Parse_Ok }; }
        case IncludePath: {
            serverOpts.includePaths.append(Source::Include(Source::Include::Type_Include, Path::resolved(value)));
            break; }
        case Isystem: {
            serverOpts.includePaths.append(Source::Include(Source::Include::Type_System, Path::resolved(value)));
            break; }
        case Define: {
            const size_t eq = value.indexOf('=');
            Source::Define def;
            if (eq == String::npos) {
                def.define = std::move(value);
            } else {
                def.define = value.left(eq);
                def.value = value.mid(eq + 1);
            }
            serverOpts.defines.append(def);
            break; }
        case DefaultArgument: {
            serverOpts.defaultArguments.append(std::move(value));
            break; }
        case LogFile: {
            logFile = std::move(value);
            logFile.resolve();
            logLevel = LogLevel::None;
            break; }
        case CrashDumpFile: {
            strncpy(crashDumpFilePath, value.constData(), sizeof(crashDumpFilePath) - 1);
            break; }
        case SetEnv: {
            putenv(&value[0]);
            break; }
        case NoWall: {
            serverOpts.options &= ~Server::Wall;
            break; }
        case Weverything: {
            serverOpts.options |= Server::Weverything;
            break; }
        case Verbose: {
            if (logLevel != LogLevel::None)
                ++logLevel;
            break; }
        case JobCount: {
            bool ok;
            serverOpts.jobCount = String(value).toULong(&ok);
            if (!ok) {
                return { String::format<1024>("Can't parse argument to -j %s. -j must be a positive integer.\n", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case HeaderErrorJobCount: {
            bool ok;
            serverOpts.headerErrorJobCount = String(value).toULong(&ok);
            if (!ok) {
                return { String::format<1024>("Can't parse argument to -H %s. -H must be a positive integer.", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case Test: {
            Path test(value);
            if (!test.resolve() || !test.isFile()) {
                return { String::format<1024>("%s doesn't seem to be a file", value.constData()), CommandLineParser::Parse_Error };
            }
            serverOpts.tests += test;
            break; }
        case TestTimeout: {
            serverOpts.testTimeout = atoi(value.constData());
            if (serverOpts.testTimeout <= 0) {
                return { String::format<1024>("Invalid argument to -z %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case PollTimer: {
            serverOpts.pollTimer = atoi(value.constData());
            if (serverOpts.pollTimer < 0) {
                return { String::format<1024>("Invalid argument to --poll-timer %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case CleanSlate: {
            serverOpts.options |= Server::ClearProjects;
            break; }
        case DisableSigHandler: {
            sigHandler = false;
            break; }
        case Silent: {
            logLevel = LogLevel::None;
            break; }
        case ExcludeFilter: {
            serverOpts.excludeFilters += String(value).split(';');
            break; }
        case SocketFile: {
            serverOpts.socketFile = std::move(value);
            serverOpts.socketFile.resolve();
            break; }
        case DataDir: {
            serverOpts.dataDir = String::format<128>("%s", Path::resolved(value).constData());
            break; }
        case IgnorePrintfFixits: {
            serverOpts.options |= Server::IgnorePrintfFixits;
            break; }
        case ErrorLimit: {
            bool ok;
            serverOpts.errorLimit = String(value).toULong(&ok);
            if (!ok) {
                return { String::format<1024>("Can't parse argument to --error-limit %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case BlockArgument: {
            serverOpts.blockedArguments << value;
            break; }
        case NoSpellChecking: {
            serverOpts.options &= ~Server::SpellChecking;
            break; }
        case LargeByValueCopy: {
            int large = atoi(value.constData());
            if (large <= 0) {
                return { String::format<1024>("Can't parse argument to -r %s", value.constData()), CommandLineParser::Parse_Error };
            }
            serverOpts.defaultArguments.append("-Wlarge-by-value-copy=" + String(value)); // ### not quite working
            break; }
        case AllowMultipleSources: {
            serverOpts.options |= Server::AllowMultipleSources;
            break; }
        case NoStartupProject: {
            serverOpts.options |= Server::NoStartupCurrentProject;
            break; }
        case NoNoUnknownWarningsOption: {
            serverOpts.options |= Server::NoNoUnknownWarningsOption;
            break; }
        case IgnoreCompiler: {
            serverOpts.ignoredCompilers.insert(Path::resolved(value));
            break; }
        case CompilerWrappers: {
            serverOpts.compilerWrappers = String(value).split(";", String::SkipEmpty).toSet();
            break; }
        case WatchSystemPaths: {
            serverOpts.options |= Server::WatchSystemPaths;
            break; }
        case RpVisitFileTimeout: {
            serverOpts.rpVisitFileTimeout = atoi(value.constData());
            if (serverOpts.rpVisitFileTimeout < 0) {
                return { String::format<1024>("Invalid argument to -Z %s", value.constData()), CommandLineParser::Parse_Error };
            }
            if (!serverOpts.rpVisitFileTimeout)
                serverOpts.rpVisitFileTimeout = -1;
            break; }
        case RpIndexerMessageTimeout: {
            serverOpts.rpIndexDataMessageTimeout = atoi(value.constData());
            if (serverOpts.rpIndexDataMessageTimeout <= 0) {
                return { String::format<1024>("Can't parse argument to -T %s.", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case RpConnectTimeout: {
            serverOpts.rpConnectTimeout = atoi(value.constData());
            if (serverOpts.rpConnectTimeout < 0) {
                return { String::format<1024>("Invalid argument to -O %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case RpConnectAttempts: {
            serverOpts.rpConnectAttempts = atoi(value.constData());
            if (serverOpts.rpConnectAttempts <= 0) {
                return { String::format<1024>("Invalid argument to --rp-connect-attempts %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case RpNiceValue: {
            bool ok;
            serverOpts.rpNiceValue = value.toLong(&ok);
            if (!ok) {
                return { String::format<1024>("Can't parse argument to -a %s.", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case SuspendRpOnCrash: {
            serverOpts.options |= Server::SuspendRPOnCrash;
            break; }
        case RpLogToSyslog: {
            serverOpts.options |= Server::RPLogToSyslog;
            break; }
        case StartSuspended: {
            serverOpts.options |= Server::StartSuspended;
            break; }
        case SeparateDebugAndRelease: {
            serverOpts.options |= Server::SeparateDebugAndRelease;
            break; }
        case Separate32BitAnd64Bit: {
            serverOpts.options |= Server::Separate32BitAnd64Bit;
            break; }
        case SourceIgnoreIncludePathDifferencesInUsr: {
            serverOpts.options |= Server::SourceIgnoreIncludePathDifferencesInUsr;
            break; }
        case MaxCrashCount: {
            serverOpts.maxCrashCount = atoi(value.constData());
            if (serverOpts.maxCrashCount <= 0) {
                return { String::format<1024>("Invalid argument to -K %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case CompletionCacheSize: {
            serverOpts.completionCacheSize = atoi(value.constData());
            if (serverOpts.completionCacheSize <= 0) {
                return { String::format<1024>("Invalid argument to -i %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case CompletionNoFilter: {
            serverOpts.options |= Server::CompletionsNoFilter;
            break; }
        case CompletionLogs: {
            serverOpts.options |= Server::CompletionLogs;
            break; }
        case MaxIncludeCompletionDepth: {
            serverOpts.maxIncludeCompletionDepth = strtoul(value.constData(), 0, 10);
            break; }
        case AllowWpedantic: {
            serverOpts.options |= Server::AllowPedantic;
            break; }
        case AllowWErrorAndWFatalErrors: {
            serverOpts.options |= Server::AllowWErrorAndWFatalErrors;
            break; }
        case EnableCompilerManager: {
            serverOpts.options |= Server::EnableCompilerManager;
            break; }
        case EnableNDEBUG: {
            serverOpts.options |= Server::EnableNDEBUG;
            break; }
        case Progress: {
            serverOpts.options |= Server::Progress;
            break; }
        case MaxFileMapCacheSize: {
            serverOpts.maxFileMapScopeCacheSize = atoi(value.constData());
            if (serverOpts.maxFileMapScopeCacheSize <= 0) {
                return { String::format<1024>("Invalid argument to -y %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
#ifdef FILEMANAGER_OPT_IN
        case FileManagerWatch: {
            serverOpts.options &= ~Server::NoFileManagerWatch;
            break; }
#else
        case NoFileManagerWatch: {
            serverOpts.options |= Server::NoFileManagerWatch;
            break; }
#endif
        case NoFileManager: {
            serverOpts.options |= Server::NoFileManager;
            break; }
        case NoFileLock: {
            serverOpts.options |= Server::NoFileLock;
            break; }
        case PchEnabled: {
            serverOpts.options |= Server::PCHEnabled;
            break; }
        case NoFilesystemWatcher: {
            serverOpts.options |= Server::NoFileSystemWatch;
            break; }
        case ArgTransform: {
            serverOpts.argTransform = Process::findCommand(value);
            if (!value.isEmpty() && serverOpts.argTransform.isEmpty()) {
                return { String::format<1024>("Invalid argument to -V. Can't resolve %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case NoComments: {
            serverOpts.options |= Server::NoComments;
            break; }
#ifdef RTAGS_HAS_LAUNCHD
        case Launchd: {
            serverOpts.options |= Server::Launchd;
            break; }
#endif
        case InactivityTimeout: {
            inactivityTimeout = atoi(value.constData()); // seconds.
            if (inactivityTimeout <= 0) {
                return { String::format<1024>("Invalid argument to --inactivity-timeout %s", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case Daemon: {
            daemon = true;
            logLevel = LogLevel::None;
            break; }
        case LogFileLogLevel: {
            if (!strcasecmp(value.constData(), "verbose-debug")) {
                logFileLogLevel = LogLevel::VerboseDebug;
            } else if (!strcasecmp(value.constData(), "debug")) {
                logFileLogLevel = LogLevel::Debug;
            } else if (!strcasecmp(value.constData(), "warning")) {
                logFileLogLevel = LogLevel::Warning;
            } else if (!strcasecmp(value.constData(), "error")) {
                logFileLogLevel = LogLevel::Error;
            } else {
                return { String::format<1024>("Unknown log level: %s options are error, warning, debug or verbose-debug", value.constData()),
                         CommandLineParser::Parse_Error };
            }
            break; }
        case WatchSourcesOnly: {
            serverOpts.options |= Server::WatchSourcesOnly;
            break; }
        case DebugLocations: {
            if (value == "clear" || value == "none") {
                serverOpts.debugLocations.clear();
            } else {
                serverOpts.debugLocations << value;
            }
            break; }
        case ValidateFileMaps: {
            serverOpts.options |= Server::ValidateFileMaps;
            break; }
        case TcpPort: {
            serverOpts.tcpPort = atoi(value.constData());
            if (!serverOpts.tcpPort) {
                return { String::format<1024>("Invalid port %s for --tcp-port", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case RpPath: {
            serverOpts.rp = std::move(value);
            if (serverOpts.rp.isFile()) {
                serverOpts.rp.resolve();
            } else {
                return { String::format<1024>("%s is not a file", value.constData()), CommandLineParser::Parse_Error };
            }
            break; }
        case LogTimestamp: {
            logFlags |= LogTimeStamp;
            break; }
        case LogFlushOption: {
            logFlags |= LogFlush;
            break; }
        case SandboxRoot: {
            serverOpts.sandboxRoot = std::move(value);
            if (!serverOpts.sandboxRoot.endsWith('/'))
                serverOpts.sandboxRoot += '/';
            if (!serverOpts.sandboxRoot.resolve() || !serverOpts.sandboxRoot.isDir()) {
                return {
                    String::format<1024>("%s is not a valid directory for sandbox-root",
                                         serverOpts.sandboxRoot.constData()),
                    CommandLineParser::Parse_Error
                    };
            }
            break; }
        case NoRealPath: {
            Path::setRealPathEnabled(false);
            serverOpts.options |= Server::NoRealPath;
            break; }
        }

        return { String(), CommandLineParser::Parse_Exec };
    };

    const std::initializer_list<CommandLineParser::Option<CommandLineParser::ConfigOptionType> > configOpts = {
        { CommandLineParser::Config, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." },
        { CommandLineParser::NoRc, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." }
    };


    const CommandLineParser::ParseStatus status = CommandLineParser::parse<OptionType>(argc, argv, opts, NullFlags, cb, "rdm", configOpts);
    switch (status.status) {
    case CommandLineParser::Parse_Error:
        fprintf(stderr, "%s\n", status.error.constData());
        return 1;
    case CommandLineParser::Parse_Ok:
        return 0;
    case CommandLineParser::Parse_Exec:
        break;
    }

    if (daemon) {
        switch (fork()) {
        case -1:
            fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno));
            return 1;
        case 0:
            setsid();
            switch (fork()) {
            case -1:
                fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno));
                return 1;
            case 0:
                break;
            default:
                return 0;
            }
            break;
        default:
            return 0;
        }
    }

    if (serverOpts.excludeFilters.isEmpty())
        serverOpts.excludeFilters = String(DEFAULT_EXCLUDEFILTER).split(';');
    if (serverOpts.compilerWrappers.isEmpty())
        serverOpts.compilerWrappers = String(DEFAULT_COMPILER_WRAPPERS).split(';').toSet();

    if (!serverOpts.headerErrorJobCount) {
        serverOpts.headerErrorJobCount = std::max<size_t>(1, serverOpts.jobCount / 2);
    } else {
        serverOpts.headerErrorJobCount = std::min(serverOpts.headerErrorJobCount, serverOpts.jobCount);
    }

    if (sigHandler) {
        signal(SIGSEGV, signalHandler);
        signal(SIGBUS, signalHandler);
        signal(SIGILL, signalHandler);
        signal(SIGABRT, signalHandler);
    }

    if (!initLogging(argv[0], logFlags, logLevel, logFile, logFileLogLevel)) {
        fprintf(stderr, "Can't initialize logging with %d %s %s\n",
                logLevel.toInt(), logFile.constData(), logFlags.toString().constData());
        return 1;
    }

#ifdef RTAGS_HAS_LAUNCHD
    if (serverOpts.options & Server::Launchd) {
        // Clamp inactivity timeout. launchd starts to worry if the
        // process runs for less than 10 seconds.

        static const int MIN_INACTIVITY_TIMEOUT = 15; // includes
        // fudge factor.

        if (inactivityTimeout < MIN_INACTIVITY_TIMEOUT) {
            inactivityTimeout = MIN_INACTIVITY_TIMEOUT;
            fprintf(stderr, "launchd mode - clamped inactivity timeout to %d to avoid launchd warnings.\n", inactivityTimeout);
        }
    }
#endif

    EventLoop::SharedPtr loop(new EventLoop);
    loop->init(EventLoop::MainEventLoop|EventLoop::EnableSigIntHandler|EventLoop::EnableSigTermHandler);

    auto server = std::make_shared<Server>();
    if (!serverOpts.tests.isEmpty()) {
        char buf[1024];
        Path path;
        while (true) {
            strcpy(buf, "/tmp/rtags-test-XXXXXX");
            if (!mkdtemp(buf)) {
                fprintf(stderr, "Failed to mkdtemp (%d)\n", errno);
                return 1;
            }
            path = buf;
            path.resolve();
            break;
        }
        serverOpts.dataDir = path;
        strcpy(buf, "/tmp/rtags-sock-XXXXXX");
        const int fd = mkstemp(buf);
        if (fd == -1) {
            fprintf(stderr, "Failed to mkstemp (%d)\n", errno);
            return 1;
        }
        close(fd);
        serverOpts.socketFile = buf;
        serverOpts.socketFile.resolve();
    }
    serverOpts.dataDir = serverOpts.dataDir.ensureTrailingSlash();

#ifdef HAVE_BACKTRACE
    if (strlen(crashDumpFilePath)) {
        if (crashDumpFilePath[0] != '/') {
            const String f = crashDumpFilePath;
            snprintf(crashDumpFilePath, sizeof(crashDumpFilePath), "%s%s", serverOpts.dataDir.constData(), f.constData());
        }
        snprintf(crashDumpTempFilePath, sizeof(crashDumpTempFilePath), "%s.tmp", crashDumpFilePath);
        Path::mkdir(serverOpts.dataDir);
        crashDumpFile = fopen(crashDumpTempFilePath, "w");
        if (!crashDumpFile) {
            fprintf(stderr, "Couldn't open temp file %s for write (%d)\n", crashDumpTempFilePath, errno);
        }
    }
#endif

    if (!server->init(serverOpts)) {
        cleanupLogging();
        return 1;
    }

    if (!serverOpts.tests.isEmpty()) {
        return server->runTests() ? 0 : 1;
    }

    loop->setInactivityTimeout(inactivityTimeout * 1000);

    loop->exec();
    const int ret = server->exitCode();
    server.reset();
    cleanupLogging();
    return ret;
}
Example #15
0
// kind defaults to US_NORMAL.
void
BaseShadow::logTerminateEvent( int exitReason, update_style_t kind )
{
	struct rusage run_remote_rusage;
	JobTerminatedEvent event;
	MyString corefile;

	memset( &run_remote_rusage, 0, sizeof(struct rusage) );

	switch( exitReason ) {
	case JOB_EXITED:
	case JOB_COREDUMPED:
		break;
	default:
		dprintf( D_ALWAYS, 
				 "UserLog logTerminateEvent with unknown reason (%d), aborting\n",
				 exitReason ); 
		return;
	}

	if (kind == US_TERMINATE_PENDING) {

		int exited_by_signal = FALSE;
		int exit_signal = 0;
		int exit_code = 0;

		getJobAdExitedBySignal(jobAd, exited_by_signal);
		if (exited_by_signal == TRUE) {
			getJobAdExitSignal(jobAd, exit_signal);
			event.normal = false;
			event.signalNumber = exit_signal;
		} else {
			getJobAdExitCode(jobAd, exit_code);
			event.normal = true;
			event.returnValue = exit_code;
		}

		/* grab usage information out of job ad */
		double real_value;
		if( jobAd->LookupFloat(ATTR_JOB_REMOTE_SYS_CPU, real_value) ) {
			run_remote_rusage.ru_stime.tv_sec = (time_t) real_value;
		}

		if( jobAd->LookupFloat(ATTR_JOB_REMOTE_USER_CPU, real_value) ) {
			run_remote_rusage.ru_utime.tv_sec = (time_t) real_value;
		}

		event.run_remote_rusage = run_remote_rusage;
		event.total_remote_rusage = run_remote_rusage;
	
		/*
		  we want to log the events from the perspective of the user
		  job, so if the shadow *sent* the bytes, then that means the
		  user job *received* the bytes
		*/
		jobAd->LookupFloat(ATTR_BYTES_SENT, event.recvd_bytes);
		jobAd->LookupFloat(ATTR_BYTES_RECVD, event.sent_bytes);

		event.total_recvd_bytes = event.recvd_bytes;
		event.total_sent_bytes = event.sent_bytes;
	
		if( exited_by_signal == TRUE ) {
			jobAd->LookupString(ATTR_JOB_CORE_FILENAME, corefile);
			event.setCoreFile( corefile.Value() );
		}

		if (!uLog.writeEvent (&event,jobAd)) {
			dprintf (D_ALWAYS,"Unable to log "
				 	"ULOG_JOB_TERMINATED event\n");
			EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event");
		}

		return;
	}

	// the default kind == US_NORMAL path

	run_remote_rusage = getRUsage();
	
	if( exitedBySignal() ) {
		event.normal = false;
		event.signalNumber = exitSignal();
	} else {
		event.normal = true;
		event.returnValue = exitCode();
	}

		// TODO: fill in local/total rusage
		// event.run_local_rusage = r;
	event.run_remote_rusage = run_remote_rusage;
		// event.total_local_rusage = r;
	event.total_remote_rusage = run_remote_rusage;
	
		/*
		  we want to log the events from the perspective of the user
		  job, so if the shadow *sent* the bytes, then that means the
		  user job *received* the bytes
		*/
	event.recvd_bytes = bytesSent();
	event.sent_bytes = bytesReceived();

	event.total_recvd_bytes = prev_run_bytes_recvd + bytesSent();
	event.total_sent_bytes = prev_run_bytes_sent + bytesReceived();
	
	if( exitReason == JOB_COREDUMPED ) {
		event.setCoreFile( core_file_name );
	}

#if 1
	set_usageAd(jobAd, &event.pusageAd);
#else
	std::string resslist;
	if ( ! jobAd->LookupString("PartitionableResources", resslist))
		resslist = "Cpus, Disk, Memory";

	StringList reslist(resslist.c_str());
	if (reslist.number() > 0) {
		int64_t int64_value = 0;
		ClassAd * puAd = new ClassAd();

		reslist.rewind();
		char * resname = NULL;
		while ((resname = reslist.next()) != NULL) {
			MyString attr;
			int64_value = -1;
			attr.formatstr("%s", resname); // provisioned value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(resname, int64_value);
			} 
			// /*for debugging*/ else { puAd->Assign(resname, 42); }
			int64_value = -2;
			attr.formatstr("Request%s", resname);	// requested value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(attr.Value(), int64_value);
			}
			// /*for debugging*/ else { puAd->Assign(attr.Value(), 99); }
			int64_value = -3;
			attr.formatstr("%sUsage", resname); // usage value
			if (jobAd->LookupInteger(attr.Value(), int64_value)) {
				puAd->Assign(attr.Value(), int64_value);
			}
		}
		event.pusageAd = puAd;
	}
#endif
	
	if (!uLog.writeEvent (&event,jobAd)) {
		dprintf (D_ALWAYS,"Unable to log "
				 "ULOG_JOB_TERMINATED event\n");
		EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event");
	}
}
Example #16
0
void
BaseShadow::terminateJob( update_style_t kind ) // has a default argument of US_NORMAL
{
	int reason;
	bool signaled;
	MyString str;

	if( ! jobAd ) {
		dprintf( D_ALWAYS, "In terminateJob() w/ NULL JobAd!" );
	}

	/* The first thing we do is record that we are in a termination pending
		state. */
	if (kind == US_NORMAL) {
		str.formatstr("%s = TRUE", ATTR_TERMINATION_PENDING);
		jobAd->Insert(str.Value());
	}

	if (kind == US_TERMINATE_PENDING) {
		// In this case, the job had already completed once and the
		// status had been saved to the job queue, however, for
		// some reason, the shadow didn't exit with a good value and
		// the job had been requeued. When this style of update
		// is used, it is a shortcut from the very birth of the shadow
		// to here, and so there will not be a remote resource or
		// anything like that set up. In this situation, we just
		// want to write the log event and mail the user and exit
		// with a good exit code so the schedd removes the job from
		// the queue. If for some reason the logging fails once again,
		// the process continues to repeat. 
		// This means at least once semantics for the termination event
		// and user email, but at no time should the job actually execute
		// again.

		int exited_by_signal = FALSE;
		int exit_signal = 0;
		int exit_code = 0;

		getJobAdExitedBySignal(jobAd, exited_by_signal);
		if (exited_by_signal == TRUE) {
			getJobAdExitSignal(jobAd, exit_signal);
		} else {
			getJobAdExitCode(jobAd, exit_code);
		}

		if (exited_by_signal == TRUE) {
			reason = JOB_COREDUMPED;
			str.formatstr("%s = \"%s\"", ATTR_JOB_CORE_FILENAME, core_file_name);
			jobAd->Insert(str.Value());
		} else {
			reason = JOB_EXITED;
		}

		dprintf( D_ALWAYS, "Job %d.%d terminated: %s %d\n",
	 		getCluster(), getProc(), 
	 		exited_by_signal? "killed by signal" : "exited with status",
	 		exited_by_signal ? exit_signal : exit_code );
		
			// write stuff to user log, but get values from jobad
		logTerminateEvent( reason, kind );

			// email the user, but get values from jobad
		emailTerminateEvent( reason, kind );

		DC_Exit( reason );
	}

	// the default path when kind == US_NORMAL

	// cleanup this shadow (kill starters, etc)
	cleanUp();

	reason = getExitReason();
	signaled = exitedBySignal();

	/* also store the corefilename into the jobad so we can recover this 
		during a termination pending scenario. */
	if( reason == JOB_COREDUMPED ) {
		str.formatstr("%s = \"%s\"", ATTR_JOB_CORE_FILENAME, getCoreName());
		jobAd->Insert(str.Value());
	}

    // Update final Job committed time
    int last_ckpt_time = 0;
    jobAd->LookupInteger(ATTR_LAST_CKPT_TIME, last_ckpt_time);
    int current_start_time = 0;
    jobAd->LookupInteger(ATTR_JOB_CURRENT_START_DATE, current_start_time);
    int int_value = (last_ckpt_time > current_start_time) ?
                        last_ckpt_time : current_start_time;

    if( int_value > 0 ) {
        int job_committed_time = 0;
        jobAd->LookupInteger(ATTR_JOB_COMMITTED_TIME, job_committed_time);
		int delta = (int)time(NULL) - int_value;
        job_committed_time += delta;
        jobAd->Assign(ATTR_JOB_COMMITTED_TIME, job_committed_time);

		float slot_weight = 1;
		jobAd->LookupFloat(ATTR_JOB_MACHINE_ATTR_SLOT_WEIGHT0, slot_weight);
		float slot_time = 0;
		jobAd->LookupFloat(ATTR_COMMITTED_SLOT_TIME, slot_time);
		slot_time += slot_weight * delta;
		jobAd->Assign(ATTR_COMMITTED_SLOT_TIME, slot_time);
    }

	CommitSuspensionTime(jobAd);

	// update the job ad in the queue with some important final
	// attributes so we know what happened to the job when using
	// condor_history...
    if (m_num_cleanup_retries < 1 &&
        param_boolean("SHADOW_TEST_JOB_CLEANUP_RETRY", false)) {
		dprintf( D_ALWAYS,
				 "Testing Failure to perform final update to job queue!\n");
		retryJobCleanup();
		return;
    }
	if( !updateJobInQueue(U_TERMINATE) ) {
		dprintf( D_ALWAYS, 
				 "Failed to perform final update to job queue!\n");
		retryJobCleanup();
		return;
	}

	// Let's maximize the effectiveness of that queue synchronization and
	// only record the job as done if the update to the queue was successful.
	// If any of these next operations fail and the shadow exits with an
	// exit code which causes the job to get requeued, it will be in the
	// "terminate pending" state marked by the ATTR_TERMINATION_PENDING
	// attribute.

	dprintf( D_ALWAYS, "Job %d.%d terminated: %s %d\n",
	 	getCluster(), getProc(), 
	 	signaled ? "killed by signal" : "exited with status",
	 	signaled ? exitSignal() : exitCode() );

	// write stuff to user log:
	logTerminateEvent( reason );

	// email the user
	emailTerminateEvent( reason );

	if( reason == JOB_EXITED && claimIsClosing() ) {
			// Startd not accepting any more jobs on this claim.
			// We do this here to avoid having to treat this case
			// identically to JOB_EXITED in the code leading up to
			// this point.
		dprintf(D_FULLDEBUG,"Startd is closing claim, so no more jobs can be run on it.\n");
		reason = JOB_EXITED_AND_CLAIM_CLOSING;
	}

	// try to get a new job for this shadow
	if( recycleShadow(reason) ) {
		// recycleShadow delete's this, so we must return immediately
		return;
	}

	// does not return.
	DC_Exit( reason );
}
Example #17
0
void Task::openMountPointTask()
{
	auto r       = utility::Task( QString( "%1 \"%2\"" ).arg( m_folderOpener ).arg( m_mpoint ) ) ;
	m_exitCode   = r.exitCode() ;
	m_exitStatus = r.exitStatus() ;
}
Example #18
0
int main(int argc, char *argv[], char* envp[])
{
    if (argc < 2) {
        fprintf(stderr, "Usage: %s prog_filename prog_aruments\n", argv[0]);
        return 3;
    }
#if 0
    if (strcmp(argv[1], "prog") != 0 && strcmp(argv[1], "all"))
    {
        fprintf(stderr, "Options for patch selection are 'progonly' or 'all'\n");
        return 3;
    }
#endif
    int patchall = 0; //strcmp(argv[1], "all") != 0;

    // Create process
    BPatch_process *appProc = bpatch.processCreate(argv[1], (const char**) &(argv[1]));

    // Load pthread into the process...
    appProc->loadLibrary("libpthread.so.0");
    
    // Get the process image    
    BPatch_image *appImage = appProc->getImage();

    // Find all the instrumentable procedures
    BPatch_Vector<BPatch_function*> *functions = appImage->getProcedures();


    /*************************************************************************
     * General function search                                               *
     *************************************************************************/

    // Find the printf function
    BPatch_Vector<BPatch_function*> printfFuncs;
    appImage->findFunction("printf", printfFuncs);
    if (printfFuncs.size() == 0)
        appImage->findFunction("_printf", printfFuncs);
    if (printfFuncs.size() == 0)
        appImage->findFunction("__printf", printfFuncs);

    if(printfFuncs.size() == 0)
    {
        fprintf(stderr, "Could not find printf() function");
        return 2;
    }

    // Find the exit function
    BPatch_Vector<BPatch_function*> exitFuncs;
        appImage->findFunction("exit", exitFuncs);
    if (exitFuncs.size() == 0)
        appImage->findFunction("_exit", exitFuncs);
    if (exitFuncs.size() == 0)
        appImage->findFunction("__exit", exitFuncs);

    if(exitFuncs.size() == 0)
    {
        fprintf(stderr, "Could not find exit() function");
        return 2;
    }

    // Find the perror function
    BPatch_Vector<BPatch_function*> perrorFuncs;
    appImage->findFunction("perror", perrorFuncs);
    if (perrorFuncs.size() == 0)
        appImage->findFunction("_perror", perrorFuncs);
    if (perrorFuncs.size() == 0)
        appImage->findFunction("__perror", perrorFuncs);

    if(perrorFuncs.size() == 0)
    {
        fprintf(stderr, "Could not find perror() function");
        return 2;
    }

    BPatch_Vector<BPatch_snippet*> mainEntryBlock;

    /************************************************************************
     * Error exit call                                                      *
     ************************************************************************/

    BPatch_Vector<BPatch_snippet*> exitArgs;
    BPatch_constExpr exitCode(-2);
    exitArgs.push_back(&exitCode);

    // Open call
    BPatch_funcCallExpr exitOnErrorCall(*exitFuncs[0], exitArgs);

 
    /************************************************************************
     * Open imitate device patch                                            *
     * **********************************************************************/

    // Find main()
    BPatch_Vector<BPatch_function*> mainFunctions;
        appImage->findFunction("main", mainFunctions);
    if (mainFunctions.size() == 0)
        appImage->findFunction("_main", mainFunctions);
    if (mainFunctions.size() == 0)
        appImage->findFunction("__main", mainFunctions);

    if(mainFunctions.size() == 0)
    {
        fprintf(stderr, "Could not find main() function");
        return 2;
    }

    // find open()
    BPatch_Vector<BPatch_function*> openFunctions;
        appImage->findFunction("open64", openFunctions);
    if (openFunctions.size() == 0)
        appImage->findFunction("open", openFunctions);
    if (openFunctions.size() == 0)
        appImage->findFunction("_open", openFunctions);
    if (openFunctions.size() == 0)
        appImage->findFunction("__open", openFunctions);

    if(openFunctions.size() == 0)
    {
        fprintf(stderr, "Could not find open() function");
        return 2;
    }

    // Get main() entry point
    BPatch_Vector<BPatch_point*> *mainPoints = mainFunctions[0]->findPoint(BPatch_entry);

    // Open call arguments
    BPatch_Vector<BPatch_snippet*> openArgs;
    BPatch_constExpr fileName("/dev/imitate0");
    BPatch_constExpr fileFlags(O_RDWR);
    openArgs.push_back(&fileName);
    openArgs.push_back(&fileFlags);

    // Open call
    BPatch_funcCallExpr openDevCall(*openFunctions[0], openArgs);

    // Allocate file descriptor
    BPatch_variableExpr *devFd = appProc->malloc(*appImage->findType("int"));

    // Assign fd with result of open call
    BPatch_arithExpr openDevice(BPatch_assign, *devFd, openDevCall);

    // defFd check
    BPatch_boolExpr devFdCheck(BPatch_lt, *devFd, BPatch_constExpr(0));
    
    // perror message
    BPatch_Vector<BPatch_snippet*> devFdErrorArgs;
    BPatch_constExpr devFdErrorMsg("Opening imitate kernel device");
    devFdErrorArgs.push_back(&devFdErrorMsg);
    BPatch_funcCallExpr devFdError(*perrorFuncs[0], devFdErrorArgs);

    BPatch_Vector<BPatch_snippet*> openErrorBlock;
    openErrorBlock.push_back(&devFdError);
    openErrorBlock.push_back(&exitOnErrorCall);

    // if (devFd < 0) { perror(...) }
    BPatch_ifExpr devFdBlock(devFdCheck, BPatch_sequence(openErrorBlock));

    mainEntryBlock.push_back(&openDevice);
    mainEntryBlock.push_back(&devFdBlock);
    

    /*************************************************************************
     * Send ioctl IMITATE_APP_RECORD to module                               *
     *************************************************************************/

    // find ioctl()
    BPatch_Vector<BPatch_function*> ioctlFunctions;
        appImage->findFunction("ioctl", ioctlFunctions);
    if (ioctlFunctions.size() == 0)
        appImage->findFunction("_ioctl", ioctlFunctions);
    if (ioctlFunctions.size() == 0)
        appImage->findFunction("__ioctl", ioctlFunctions);

    if(ioctlFunctions.size() == 0)
    {
        fprintf(stderr, "Could not find ioctl() function");
        return 2;
    }

    // ioctl() arguments
    BPatch_Vector<BPatch_snippet*> ioctlArgs;
    BPatch_constExpr operation(IMITATE_APP_RECORD);
    fprintf(stderr, "PPID: %d\n", getppid());
    BPatch_constExpr monitorPid(getppid());
    ioctlArgs.push_back(devFd);
    ioctlArgs.push_back(&operation);
    ioctlArgs.push_back(&monitorPid);

    // ioctl() call
    BPatch_funcCallExpr ioctlCall(*ioctlFunctions[0], ioctlArgs);

    // ioctl() result check
    BPatch_boolExpr ioctlCheck(BPatch_lt, ioctlCall, BPatch_constExpr(0));
    
    // perror message
    BPatch_Vector<BPatch_snippet*> ioctlErrorArgs;
    BPatch_constExpr ioctlErrorMsg("Notifying imitate kernel driver of RECORD");
    ioctlErrorArgs.push_back(&ioctlErrorMsg);
    BPatch_funcCallExpr ioctlError(*perrorFuncs[0], ioctlErrorArgs);

    BPatch_Vector<BPatch_snippet*> ioctlErrorBlock;
    ioctlErrorBlock.push_back(&ioctlError);
    ioctlErrorBlock.push_back(&exitOnErrorCall);

    // if (ioctl(...) < 0) { perror(...) }
    BPatch_ifExpr ioctlBlock(ioctlCheck, BPatch_sequence(ioctlErrorBlock));

    // Add ioctl check to entry block
    mainEntryBlock.push_back(&ioctlBlock);

    /*************************************************************************
     * Counter mmap()                                                        *
     *************************************************************************/

    // Find the mmap function
    BPatch_Vector<BPatch_function*> mmapFuncs;
        appImage->findFunction("mmap", mmapFuncs);
    if (mmapFuncs.size() == 0)
        appImage->findFunction("_mmap", mmapFuncs);
    if (mmapFuncs.size() == 0)
        appImage->findFunction("__mmap", mmapFuncs);

    if(mmapFuncs.size() == 0)
    {
        fprintf(stderr, "Could not find mmap() function");
        return 2;
    }

    // Allocate counter
    BPatch_variableExpr *counterAddr = appProc->malloc(sizeof(sched_counter_t*));
    sched_counter_t counterVal = 0;
    counterAddr->writeValue(&counterVal, sizeof(sched_counter_t*), false);

    // Notify kernel of address
    BPatch_Vector<BPatch_snippet*> mmapArgs;
    BPatch_constExpr mmapStart(0);
    BPatch_constExpr mmapLength(sizeof(sched_counter_t));
    BPatch_constExpr mmapProt(PROT_READ | PROT_WRITE);
    BPatch_constExpr mmapFlags(MAP_SHARED);
    BPatch_constExpr mmapOffset(0);

    mmapArgs.push_back(&mmapStart);
    mmapArgs.push_back(&mmapLength);
    mmapArgs.push_back(&mmapProt);
    mmapArgs.push_back(&mmapFlags);
    mmapArgs.push_back(devFd);
    mmapArgs.push_back(&mmapOffset);

    // mmap() call
    BPatch_funcCallExpr mmapCall(*mmapFuncs[0], mmapArgs);

    // assign result to counterAddr
    BPatch_arithExpr mmapAssign(BPatch_assign, *counterAddr, mmapCall);

    // Add to entry block
    mainEntryBlock.push_back(&mmapAssign);

    // mmap() result check
    BPatch_boolExpr mmapCheck(BPatch_eq, *counterAddr, BPatch_constExpr(MAP_FAILED));

    // perror message
    BPatch_Vector<BPatch_snippet*> mmapErrorArgs;
    BPatch_constExpr mmapErrorMsg("Memory mapping schedule (back edge) counter");
    mmapErrorArgs.push_back(&mmapErrorMsg);
    BPatch_funcCallExpr mmapError(*perrorFuncs[0], mmapErrorArgs);

    BPatch_Vector<BPatch_snippet*> mmapErrorBlock;
    mmapErrorBlock.push_back(&mmapError);
    mmapErrorBlock.push_back(&exitOnErrorCall);

    // if (mmap(...) == MAP_FAILED) { perror(...) }
    BPatch_ifExpr mmapBlock(mmapCheck, BPatch_sequence(mmapErrorBlock));

    mainEntryBlock.push_back(&mmapBlock);


    // Patch main entry
    BPatch_sequence mainEntrySeq(mainEntryBlock);
    appProc->insertSnippet(mainEntrySeq, *mainPoints);


    /*************************************************************************
     * Back-edge patching                                                    *
     *************************************************************************/

#if 0
    printf("intCounter address: %x\n PID: %d\n", intCounter->getBaseAddr(), appProc->getPid());
    fflush(stdout);
#endif

    // Find the mutex lock/unlock functions
    BPatch_Vector<BPatch_function*> mutexLockFunctions;
        appImage->findFunction("pthread_mutex_lock", mutexLockFunctions);
    if (mutexLockFunctions.size() == 0)
        appImage->findFunction("_pthread_mutex_lock", mutexLockFunctions);
    if (mutexLockFunctions.size() == 0)
        appImage->findFunction("__pthread_mutex_lock", mutexLockFunctions);

    if(mutexLockFunctions.size() == 0)
    {
        fprintf(stderr, "Could not find pthread_mutex_lock() function");
        return 2;
    }

    BPatch_Vector<BPatch_function*> mutexUnlockFunctions;
        appImage->findFunction("pthread_mutex_unlock", mutexUnlockFunctions);
    if (mutexUnlockFunctions.size() == 0)
        appImage->findFunction("_pthread_mutex_unlock", mutexUnlockFunctions);
    if (mutexUnlockFunctions.size() == 0)
        appImage->findFunction("__pthread_mutex_unlock", mutexUnlockFunctions);

    if(mutexUnlockFunctions.size() == 0)
    {
        fprintf(stderr, "Could not find pthread_mutex_unlock() function");
        return 2;
    }

    // Allocate a mutex
    pthread_mutex_t mutexValue = PTHREAD_MUTEX_INITIALIZER;
    BPatch_variableExpr *mutex = appProc->malloc(sizeof(pthread_mutex_t));
    mutex->writeValue(&mutexValue, sizeof(pthread_mutex_t), false);

    // Build mutex lock call
    BPatch_Vector<BPatch_snippet*> mutexArgs;
    BPatch_constExpr mutexAddress(mutex->getBaseAddr());

    mutexArgs.push_back(&mutexAddress);

    BPatch_funcCallExpr mutexLockCall(*mutexLockFunctions[0], mutexArgs);
    BPatch_funcCallExpr mutexUnlockCall(*mutexUnlockFunctions[0], mutexArgs);

    BPatch_arithExpr derefCounter(BPatch_deref, *counterAddr);

    // Create 'increment counter' snippet
    BPatch_arithExpr addOneToCounter(BPatch_assign, derefCounter,
        BPatch_arithExpr(BPatch_plus, derefCounter, BPatch_constExpr(1)));

    BPatch_Vector<BPatch_snippet*> snippet;
    snippet.push_back(&mutexLockCall);
    snippet.push_back(&addOneToCounter);
    snippet.push_back(&mutexUnlockCall);

    BPatch_sequence addOneAtomic(snippet);

    char *name = (char*) malloc(sizeof(char)*200);
    char *modname = (char*) malloc(sizeof(char)*200);
    if (! (name && modname))
    {
        fprintf(stderr, "%s %d: Out of memory!", __FILE__, __LINE__);
        return 1;
    }

    appProc->beginInsertionSet();

    // Iterate through the procedures
    for (int i = 0; i < functions->size(); i++)
    {
        (*functions)[i]->getName(name, 199);
        (*functions)[i]->getModuleName(modname, 199);
        if ((patchall && strcmp(modname, "DEFAULT_MODULE") != 0) ||
            strncmp(name, "pthread", 7) == 0 ||
            strncmp(modname, "libpthread", 10) == 0 ||
            strncmp(modname, "libdyninst", 10) == 0 ||
            (name[0] == '_' && name[1] != '_' && strncmp(modname, "libc", 4) == 0))
            continue;

        fprintf(stderr, "patcher: Patching function: '%s' (%s)", name, modname);

        // Patch back-edge for call
        if (strcmp(name, "main") != 0)
            appProc->insertSnippet(addOneAtomic, *((*functions)[i]->findPoint(BPatch_entry)));

        // Get the control flow graph for the procedure
        BPatch_flowGraph *graph = (*functions)[i]->getCFG();

        // Find the loops
        BPatch_Vector<BPatch_basicBlockLoop*> *loops = new BPatch_Vector<BPatch_basicBlockLoop*>();
        graph->getLoops(*loops);
    
        // Patch the loop back-edges
        for(int j = 0; j < loops->size(); j++)
        {
            appProc->insertSnippet(addOneAtomic, *((*loops)[j]->getBackEdge()->getPoint()));
            fprintf(stderr, ".", (int) (*loops)[j]->getBackEdge()->getPoint()->getAddress());
        }
        fprintf(stderr, "\n");

        // Free the loops found
        delete(loops);
    }

    fprintf(stderr, "Finalising patches...");
    fflush(stderr);
    appProc->finalizeInsertionSet(false);
    fprintf(stderr, "Done.\n----------------------------------------\n");

    // Clear up memory used to store the name
    free(name);
    free(modname);


#if 0
    /*************************************************************************
     * Exit point counter print patch                                        *
     *************************************************************************/

    // Patch exit() function to print out no of back branches at the end
    // Get exit() exit point
    BPatch_Vector<BPatch_point*> *exitPoints = exitFuncs[0]->findPoint(BPatch_entry);

    // Build printf() call:
    //    printf("Total Total Back-branches: %d\n", counter);

    // Build arguments to printf()
    BPatch_Vector<BPatch_snippet*> printfArgs;
    BPatch_constExpr formatString("Total Back-branches: %d\n");

    printfArgs.push_back(&formatString);
    printfArgs.push_back(&derefCounter);

    // Build call to printf()
    BPatch_funcCallExpr printfCall(*printfFuncs[0], printfArgs);

    // Patch into exit()
    appProc->insertSnippet(printfCall, *exitPoints);
#endif

    // Continue mutatee...
    appProc->continueExecution();

    // Wait for mutatee to finish
    while (!appProc->isTerminated())
    {
        bpatch.waitForStatusChange();
    }

    fprintf(stderr, "----------------------------------------\n");
    fprintf(stderr, "Done.\n");
    return 0;
}
Example #19
0
void keyDialog::openVolume()
{
	int keyType = m_ui->cbKeyType->currentIndex() ;

	if( m_volumeIsEncFs ){

		if( keyType == keyDialog::Key ){

			m_key = m_ui->lineEditKey->text() ;

		}else if( keyType == keyDialog::keyfile ){

			QFile f( m_ui->lineEditKey->text() ) ;

			f.open( QIODevice::ReadOnly ) ;

			m_key = f.readAll() ;

		}else if( keyType == keyDialog::plugin ){

			/*
			 * m_key is already set
			 */
		}

		return this->encfsMount() ;
	}

	if( m_ui->lineEditKey->text().isEmpty() ){
		if( keyType == keyDialog::Key ){
			;
		}else if( keyType == keyDialog::plugin ){
			DialogMsg msg( this ) ;
			msg.ShowUIOK( tr( "ERROR" ),tr( "Plug in name field is empty" ) ) ;
			m_ui->lineEditKey->setFocus() ;
			return this->enableAll() ;
		}else if( keyType == keyDialog::keyfile ){
			DialogMsg msg( this ) ;
			msg.ShowUIOK( tr( "ERROR" ),tr( "Keyfile field is empty" ) ) ;
			m_ui->lineEditKey->setFocus() ;
			return this->enableAll() ;
		}
	}

	QString test_name = m_ui->lineEditMountPoint->text() ;
	if( test_name.contains( "/" ) ){
		DialogMsg msg( this ) ;
		msg.ShowUIOK( tr( "ERROR" ),tr( "\"/\" character is not allowed in the mount name field" ) ) ;
		m_ui->lineEditKey->setFocus() ;
		return this->enableAll() ;
	}

	QString m ;
	if( keyType == keyDialog::Key ){

		QString addr = utility::keyPath() ;
		m = QString( "-f %1" ).arg( addr ) ;

		QString key = m_ui->lineEditKey->text() ;

		utility::keySend( addr,key ) ;

	}else if( keyType == keyDialog::keyfile ){

		QString e = m_ui->lineEditKey->text().replace( "\"","\"\"\"" ) ;
		m = "-f \"" + utility::resolvePath( e ) + "\"" ;

	}else if( keyType == keyDialog::plugin ){

		if( m_key.isEmpty() ){

			m = "-G " + m_ui->lineEditKey->text().replace( "\"","\"\"\"" ) ;
		}else{

			QString addr = utility::keyPath() ;
			m = QString( "-f %1" ).arg( addr ) ;

			utility::keySend( addr,m_key ) ;
		}
	}else if( keyType == keyDialog::tcryptKeys ){

		QString addr = utility::keyPath() ;
		m = QString( "-f %1 " ).arg( addr ) ;

		utility::keySend( addr,m_key ) ;
	}else{
		qDebug() << "ERROR: Uncaught condition" ;
	}

	QString volume = m_path ;
	volume.replace( "\"","\"\"\"" ) ;

	QString exe = zuluMountPath ;

	if( m_ui->checkBoxShareMountPoint->isChecked() ){
		exe += " -M -m -d \"" + volume + "\"" ;
	}else{
		exe += " -m -d \"" + volume + "\"" ;
	}

	if( m_ui->checkBoxOpenReadOnly->isChecked() ){
		exe += " -e ro" ;
	}else{
		exe += "  e rw" ;
	}

	QString mountPoint = m_ui->lineEditMountPoint->text() ;
	mountPoint.replace( "\"","\"\"\"" ) ;

	exe += " -z \"" + mountPoint + "\"" ;

	if( !m_options.isEmpty() ){

		exe += " -Y " + m_options ;
	}

	if( !m_deviceOffSet.isEmpty() ){

		exe += " -o " + m_deviceOffSet ;
	}

	if( !m_keyFiles.isEmpty() ){

		for( const auto& it : m_keyFiles ){

			QString e = it ;
			e.replace( "\"","\"\"\"" ) ;

			exe += " -F \"" + e + "\"" ;
		}
	}

	if( m_veraCryptVolume ){

		if( m_veraCryptPIMValue > 0 ){

			exe += " -t veracrypt." + QString::number( m_veraCryptPIMValue ) + " " + m ;
		}else{
			exe += " -t veracrypt " + m ;
		}
	}else{
		exe += " " + m ;
	}

	m_veraCryptWarning.show( m_veraCryptVolume ) ;

	m_working = true ;

	auto s = utility::Task::run( utility::appendUserUID( exe ) ).await() ;

	m_working = false ;

	m_veraCryptWarning.stopTimer() ;

	if( s.success() ){

		if( utility::mapperPathExists( m_path ) ) {
			/*
			 * The volume is reported as opened and it actually is
			 */
			m_success( utility::mountPath( mountPoint ) ) ;
		}else{
			/*
			 * The volume is reported as opened but it isnt,possible reason is a backe end crash
			 */

			DialogMsg msg( this ) ;

			msg.ShowUIOK( tr( "ERROR" ),tr( "An error has occured and the volume could not be opened" ) ) ;
			m_cancel() ;
		}
		this->HideUI() ;
	}else{
		m_veraCryptWarning.hide() ;

		if( s.exitCode() == 12 && m_ui->cbKeyType->currentIndex() == keyDialog::plugin ){
			/*
			 * A user cancelled the plugin
			 */
			this->enableAll() ;
		}else{

			QString z = s.output() ;
			z.replace( tr( "ERROR: " ),"" ) ;

			DialogMsg msg( this ) ;

			msg.ShowUIOK( tr( "ERROR" ),z ) ;

			if( m_ui->cbKeyType->currentIndex() == keyDialog::Key ){
				m_ui->lineEditKey->clear() ;
			}
			this->enableAll() ;
			m_ui->lineEditKey->setFocus() ;
		}
	}
}