/* Process Monitor thread, for monitoring processes running time */ void * processMonitor(void * skip) { int pid, status; struct timespec tm; while(1) { M_LOCK(&mutexRunningProcesses); while(runningProcesses==0) { if (exitCalled && processesWaitingToRun==0) { pthread_exit(NULL); } C_WAIT(&condRunningProcesses, &mutexRunningProcesses); } M_UNLOCK(&mutexRunningProcesses); pid = wait(&status); if (pid < 0) { if (errno == EINTR) continue; else { perror("Error waiting for child"); exit (EXIT_FAILURE); } } else { clock_gettime( CLOCK_MONOTONIC, &tm); M_LOCK(&mutexRunningProcesses); runningProcesses--; C_SIGNAL(&condFreeSlots); M_UNLOCK(&mutexRunningProcesses); } endProcess(pid, status, tm); } }
void ProcessSlaveActivity::main() { #ifdef TIME_ACTIVITIES if (timeActivities) lastCycles = get_cycles_now(); #endif try { process(); } catch (IException *_e) { IThorException *e = QUERYINTERFACE(_e, IThorException); if (e) { if (!e->queryActivityId()) { e->setGraphId(container.queryOwner().queryGraphId()); e->setActivityKind(container.getKind()); e->setActivityId(container.queryId()); } } else { e = MakeActivityException(this, _e); if (QUERYINTERFACE(_e, ISEH_Exception)) { IThorException *e2 = MakeThorFatal(e, TE_SEH, "FATAL: (SEH)"); e->Release(); e = e2; } _e->Release(); } ActPrintLog(e, NULL); exception.setown(e); } catch (std::exception & es) { StringBuffer m("FATAL std::exception "); if(dynamic_cast<std::bad_alloc *>(&es)) m.append("out of memory (std::bad_alloc)"); else m.append("standard library exception (std::exception ").append(es.what()).append(")"); m.appendf(" in %"ACTPF"d",container.queryId()); ActPrintLogEx(&queryContainer(), thorlog_null, MCerror, "%s", m.str()); exception.setown(MakeThorFatal(NULL, TE_UnknownException, "%s", m.str())); } catch (CATCHALL) { ActPrintLogEx(&queryContainer(), thorlog_null, MCerror, "Unknown exception thrown in process()"); exception.setown(MakeThorFatal(NULL, TE_UnknownException, "FATAL: Unknown exception thrown by ProcessThread")); } try { endProcess(); } catch (IException *_e) { ActPrintLog(_e, "Exception calling activity endProcess"); fireException(_e); exception.set(_e); _e->Release(); } }
void ConnectionClient::finishProcess() { TIME_SCOPE_DURATION("ConnectionClient::finishProcess"); processAliveTimer.stop(); disconnectProcessFinished(); endProcess(); disconnectFromServer(); terminateProcess(); killProcess(); process_.reset(); serverProxy_.resetCounter(); }
void * executeProcess(void *vargp){ /*-----------------------------------DESCRIÇÃO--------------------------------* * * * Função para a criação de uma thread, recebe uma struct definida no iní- * * cio do programa como parâmetro e a partir dela, é possível se executar * * com flexiblidade o pequeno algoritmo descrito. * * * * Essa função recebe como parâmetro uma struct que contém os dois únicos * * parâmetros necessários. O cabeçalho da memória e o endereço do processo * * que criou essa thread. * * * * Para simular a execução de um processo, na verdade, fazemos com que o * * processo aguarde um tempo randômico antes de ser finalizado. Esse tempo * * está entre 1 e MAX_PROCESS_TIME que é uma definição do sistema. * * * * Após a espera desse tempo, o processo chama sua própria função de exclu- * * são e aguarda até que o acesso a lista seja liberado pela fechadura * * mutex_listModify. Então, encerra o processo e libera a fechadura. * * * *----------------------------------------------------------------------------*/ execution_arg *exec_arg = (execution_arg *) vargp; time_t t; _program_time processTime; srand((unsigned) time(&t)); processTime = 1 + rand() % (MAX_PROCESS_TIME - 1); while(processTime--){ pthread_mutex_lock(&mutex_play); while(!play) pthread_cond_wait(&cond_play, &mutex_play); pthread_mutex_unlock(&mutex_play); sleep(1); } pthread_mutex_lock(&mutex_listModify); endProcess(exec_arg->selfCase, exec_arg->memory); pthread_mutex_unlock(&mutex_listModify); pthread_exit((void *)NULL); }
void BatchProcessImagesDialog::processAborted(bool removeFlag) { kDebug() << "BatchProcessImagesDialog::processAborted"; BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>(**m_listFile2Process_iterator); m_listFiles->scrollToItem(m_listFiles->currentItem()); item->changeResult(i18n("Aborted.")); item->changeError(i18n("process aborted by user")); if (removeFlag == true) { // Try to delete de destination ! KUrl deleteImage = m_ui->m_destinationUrl->url(); deleteImage.addPath(item->nameDest()); if (KIO::NetAccess::exists(deleteImage, KIO::NetAccess::DestinationSide, kapp->activeWindow()) == true) KIO::NetAccess::del(deleteImage, kapp->activeWindow()); } endProcess(); }
Job* Parser::parseLine (void) { job = new Job(); currState = PARSCMD; int i, length, curr; int rflag; // Limpa o buffer de entrada para evitar loop infinito strcpy(line, "\0"); std::cin.clear(); std::cin.getline (line, MAX_LENGTH); i = 0; while (i < length && line[i] == ' ') i++; length = strlen(line+i); // Checa se a linha nao estava em branco if (length == 0) { job->addFlag (shooSH_NOP); return job; } else { while (line[--length] == ' '); // pega os espacos do fim length++; if (strcmp (line+i, "exit") == 0) { //builtin job->addFlag (shooSH_EXIT); return job; } } if ((line+i)[length-1] == '&') job->setCommand (std::string (line+i, length-1)); else job->setCommand (std::string (line+i, length)); while (currState != PARSSUCCESS && currState != PARSFAIL) { if (currState == PARSCMD) { newProcess(); newWord(); rflag = 0; // pega espacos while (i < length && line[i] == ' ') i++; // esperava um comando, mas nao veio nada (usado para pipe) if (i == length) { currState = PARSFAIL; } else { // le ate encontrar um espaco while (i < length && line[i] != ' ') cmdList[cmdListSize][currChar++] = line[i++]; currState = PARSNEXT; } endWord(); } else if (currState == PARSNEXT) { // le espaco while (i < length && line[i] == ' ') i++; if (i == length) { //chegou ao fim da linha currState = PARSSUCCESS; endProcess(); } else { // procura token switch (line[i]) { case '<': i++; currState = PARSRIN; break; case '>': i++; currState = PARSROUT; break; case '2': //pode ser argumento ou redirecionamento de erro i++; currState = PARSTWO; break; case '|': i++; job->addFlag (shooSH_PIPE); endProcess(); currState = PARSCMD; break; case '&': i++; job->addFlag (shooSH_BG); endProcess(); currState = PARSSUCCESS; break; default: currState = PARSPARAM; } } } else if (currState == PARSPARAM) { newWord(); while (i < length && line[i] != ' ' && line[i] != '\"' && line[i] != '\'') cmdList[cmdListSize][currChar++] = line[i++]; if (line[i] == '\"') { i++; while (i < length && line[i] != '\"') cmdList[cmdListSize][currChar++] = line[i++]; if (i == length) { endWord(); currState = PARSFAIL; } else { i++; endWord(); currState = PARSNEXT; } } else if (line[i] == '\'') { i++; while (i < length && line[i] != '\'') cmdList[cmdListSize][currChar++] = line[i++]; if (i == length) { endWord(); currState = PARSFAIL; } else { i++; endWord(); currState = PARSNEXT; } } else { endWord(); currState = PARSNEXT; } } else if (currState == PARSTWO) { if (line[i] == '>') { i++; endWord(); currState = PARSRERR; } else { i--; currState = PARSPARAM; } endWord(); } else if (currState == PARSRERR) { if (line[i] == '>') { // append i++; rflag = REDERRA; } else { // trunc rflag = REDERRT; } currState = PARSFILENAME; } else if (currState == PARSRIN) { rflag = REDIN; currState = PARSFILENAME; } else if (currState == PARSROUT) { if (line[i] == '>') { // append i++; rflag = REDOUTA; } else { // trunc rflag = REDOUTT; } currState = PARSFILENAME; } else if (currState == PARSFILENAME) { while (i < length && line[i] == ' ') i++; if (i == length) currState = PARSFAIL; else { curr = 0; if (line[i] == '"') { // le nomes como "file name" i++; while (i < length && line[i] != '"') filename[curr++] = line[i++]; if (i == length) currState = PARSFAIL; else i++; } else if (line[i] == '\'') { // le nomes do tipo 'file name' i++; while (i < length && line[i] != '\'') filename[curr++] = line[i++]; if (i == length) currState = PARSFAIL; else i++; } else { // le nomes do tipo filename while (i < length && line[i] != ' ') filename[curr++] = line[i++]; } filename[curr] = '\0'; job->setProcessFile (filename, rflag); currState = PARSNEXT; } } } if (currState == PARSFAIL) job->addFlag (shooSH_FAIL); return job; }
void ServerControl::start() { try { TRACE("start() called\r\n"); if (busy) throw "Server is already being monitored"; busy = true; updateStatus(STATUS_UNKNOWN,STATUS_START); createProcess(); updateStatus(STATUS_UP,STATUS_OK); int counter = 1; while (*go) { Sleep(time_pause); // wait 3 seconds try { if (!pingOnce()) { counter+=2; // always add 2 then subtract 1 at end of loop updateStatus(STATUS_UNKNOWN,STATUS_NO_REPLY); } } catch (char*) // on errors in the pingonce, something bad happened so we let the process respawn immediately { updateStatus(STATUS_DOWN,STATUS_NO_REPLY); counter = 11; } if (counter > 10) // server has been gone for too long, or error { updateStatus(STATUS_DOWN,STATUS_STOP); endProcess(); updateStatus(STATUS_UNKNOWN,STATUS_START); counter = 0; createProcess(); updateStatus(STATUS_UP,STATUS_OK); } if (counter > 0) // subtract one to lower the number back to 0 when server is up (mapchanges etc) { if (counter == 1) updateStatus(STATUS_UP,STATUS_OK); counter--; } } if (!no_kill) // turned on if servers should remain active after program end { updateStatus(STATUS_UNKNOWN,STATUS_STOP); endProcess(); updateStatus(STATUS_DOWN,STATUS_STOPPED); } busy = false; TRACE("start() stopped"); } catch (...) { busy = false; // whatever happens, we're not busy anymore! throw; } }
void SmbView::slotProcessExited(KProcess *) { endProcess(); }
Anchor::~Anchor() { // Important: FIRST end the child process // THEN stop the event loop. endProcess(); Process::stop(); }
void BatchProcessImagesDialog::slotFinished() { if (m_convertStatus == PROCESS_DONE) { // processAborted() has already been called. No need to show the warning. return; } BatchProcessImagesItem *item = static_cast<BatchProcessImagesItem*>(**m_listFile2Process_iterator); m_listFiles->scrollToItem(m_listFiles->currentItem()); if (m_ProcessusProc->exitStatus() == QProcess::CrashExit) { int code = KMessageBox::warningContinueCancel(this, i18n("The 'convert' program from 'ImageMagick' package has been stopped abnormally"), i18n("Error running 'convert'")); if (code == KMessageBox::Cancel) { processAborted(true); } else { item->changeResult(i18nc("batch process result", "Failed.")); item->changeError(i18n("'convert' program from 'ImageMagick' package " "has been stopped abnormally.")); ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float) m_progressStatus * (float) 100 / (float) m_nbItem)); if (**m_listFile2Process_iterator) startProcess(); else endProcess(); } return; } int ValRet = m_ProcessusProc->exitCode(); kWarning() << "Convert exit (" << ValRet << ")"; switch (ValRet) { case 0: { // Process finished successfully ! item->changeResult(i18n("OK")); item->changeError(i18n("no processing error")); processDone(); KUrl src; src.setPath(item->pathSrc()); KUrl dest = m_ui->m_destinationUrl->url(); dest.addPath(item->nameDest()); QString errmsg; KUrl::List urlList; urlList.append(src); urlList.append(dest); iface()->refreshImages(urlList); if (!item->overWrote()) { // Do not add an entry if there was an image at the location already. bool ok = iface()->addImage(dest, errmsg); if (!ok) { int code = KMessageBox::warningContinueCancel(this, i18n( "<qt>Error adding image to application; error message was: " "<b>%1</b></qt>", errmsg), i18n("Error Adding Image to Application")); if (code == KMessageBox::Cancel) { slotProcessStop(); break; } else { item->changeResult(i18nc("batch process result", "Failed.")); } } } if (src != dest) { // Clone data in KIPI host application. KPImageInfo info(src); info.cloneData(dest); // Move XMP sidecar file. KPMetadata::moveSidecar(src, dest); } if (m_ui->m_removeOriginal->isChecked() && src != dest) { KUrl deleteImage(item->pathSrc()); if (KIO::NetAccess::del(deleteImage, kapp->activeWindow()) == false) { item->changeResult(i18nc("batch process result", "Warning:")); item->changeError(i18n("cannot remove original image file.")); } else { iface()->delImage(item->pathSrc()); } } break; } case 15: { // process aborted ! processAborted(true); break; } default : { // Processing error ! item->changeResult(i18nc("batch process result", "Failed.")); item->changeError(i18n("cannot process original image file.")); break; } } ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem)); if (**m_listFile2Process_iterator) startProcess(); else endProcess(); }
bool BatchProcessImagesDialog::startProcess() { if (m_convertStatus == STOP_PROCESS) { endProcess(); return true; } QString targetAlbum = m_ui->m_destinationUrl->url().path(); //TODO check if it is valid also for remote URL's // this is a workarond for bug 117397 QFileInfo dirInfo(targetAlbum + '/'); if (!dirInfo.isDir() || !dirInfo.isWritable()) { KMessageBox::error(this, i18n("You must specify a writable path for your output file.")); endProcess(); return true; } BatchProcessImagesItem* item = static_cast<BatchProcessImagesItem*>(**m_listFile2Process_iterator); m_listFiles->setCurrentItem(item); // Lock current item into KIPI host application KPFileReadLocker(iface(), item->pathSrc()); if (prepareStartProcess(item, targetAlbum) == false) // If there is a problem during the { // preparation -> pass to the next item! ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem)); item = static_cast<BatchProcessImagesItem*>(**m_listFile2Process_iterator); m_listFiles->setCurrentItem(item); if (**m_listFile2Process_iterator) { startProcess(); return true; } else { endProcess(); return true; } } KUrl desturl(targetAlbum + '/' + item->nameDest()); if (KIO::NetAccess::exists(desturl, KIO::NetAccess::DestinationSide, kapp->activeWindow()) == true) { switch (overwriteMode()) { case OVERWRITE_ASK: { int ValRet = KMessageBox::warningYesNoCancel(this, i18n("The destination file \"%1\" already exists;\n" "do you want overwrite it?", item->nameDest()), i18n("Overwrite Destination Image File"), KStandardGuiItem::cont()); if (ValRet == KMessageBox::No) { item->changeResult(i18n("Skipped.")); item->changeError(i18n("destination image file already exists (skipped by user).")); ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem)); if (**m_listFile2Process_iterator) { startProcess(); return true; } else { endProcess(); return true; } } else if (ValRet == KMessageBox::Cancel) { processAborted(false); return false; } else { item->setDidOverWrite(true); } break; } case OVERWRITE_RENAME: { QFileInfo Target(targetAlbum + '/' + item->nameDest()); QString newFileName = RenameTargetImageFile(&Target); if (newFileName.isNull()) { item->changeResult(i18nc("batch process result", "Failed.")); item->changeError(i18n("destination image file already exists and cannot be renamed.")); ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem)); if (**m_listFile2Process_iterator) { startProcess(); return true; } else { endProcess(); return true; } } else { QFileInfo newTarget(newFileName); item->changeNameDest(newTarget.fileName()); } break; } case OVERWRITE_SKIP: { item->changeResult(i18n("Skipped.")); item->changeError(i18n("destination image file already exists (skipped automatically).")); ++*m_listFile2Process_iterator; ++m_progressStatus; m_ui->m_progress->setValue((int)((float)m_progressStatus *(float)100 / (float)m_nbItem)); if (**m_listFile2Process_iterator) { startProcess(); return true; } else { endProcess(); return true; } break; } case OVERWRITE_OVER: // In this case do nothing : 'convert' default mode... item->setDidOverWrite(true); break; default: { endProcess(); return true; } } } m_ProcessusProc = new KProcess(this); m_ProcessusProc->setOutputChannelMode(KProcess::MergedChannels); initProcess(m_ProcessusProc, item, targetAlbum); m_commandLine = m_ProcessusProc->program().join(" "); item->changeOutputMess(m_commandLine + "\n\n"); connect(m_ProcessusProc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished())); connect(m_ProcessusProc, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); m_ProcessusProc->start(); if (!m_ProcessusProc->waitForStarted()) { KMessageBox::error(this, i18n("Cannot start 'convert' program from 'ImageMagick' package;\n" "please check your installation.")); delete m_ProcessusProc; m_ProcessusProc = 0; return false; } return true; }
// // AbiPaint editImage // ------------------ // This is the function that we actually call to invoke the image editor. // // parameters are: // AV_View* v // EV_EditMethodCallData *d // static DECLARE_ABI_PLUGIN_METHOD(editImage) { UT_UNUSED(v); // Get the current view that the user is in. XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView()); // // get values from preference (initial plugin execution should have set sensible defaults) // UT_String imageApp; // holds MAXPATH\appName <space> MAXPATH\imagefilename bool bLeaveImageAsPNG; // read stuff from the preference value if (!prefsScheme->getValue(ABIPAINT_PREF_KEY_szProgramName, imageApp)) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); getDefaultApp(imageApp, bLeaveImageAsPNG); } // now that we have program name, try to get other flag (allows overriding default value) // Note: we allow overriding, otherwise if we don't adhere to user's setting // then the use BMP or not menu should be greyed to note it has no effect prefsScheme->getValueBool(ABIPAINT_PREF_KEY_bLeaveImageAsPNG, &bLeaveImageAsPNG); // // generate a temp file name... // char *szTempFileName = NULL; GError *err = NULL; gint fp = g_file_open_tmp ("XXXXXX", &szTempFileName, &err); if (err) { g_warning ("%s", err->message); g_error_free (err); err = NULL; return FALSE; } close(fp); UT_String szTmpPng = szTempFileName; szTmpPng += ".png"; UT_String szTmp = szTmpPng; // default: our temp file is the created png file PT_DocPosition pos = pView->saveSelectedImage((const char *)szTmpPng.c_str()); if(pos == 0) { remove(szTempFileName); g_free (szTempFileName); szTempFileName = NULL; pFrame->showMessageBox("You must select an Image before editing it", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); return false; } #ifdef ENABLE_BMP // // Convert png into bmp for best compatibility with Windows programs // NOTE: probably looses detail/information though!!! so if possible use PNG // if (!bLeaveImageAsPNG) { szTmp = szTempFileName; szTmp += ".bmp"; // our temp file is a bmp file if (convertPNG2BMP(szTmpPng.c_str(), szTmp.c_str())) { pFrame->showMessageBox("Unable to convert PNG image data to BMP for external program use!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); UT_ASSERT(UT_SHOULD_NOT_HAPPEN); remove(szTempFileName); g_free (szTempFileName); szTempFileName = NULL; remove(szTmpPng.c_str()); return false; } // remove(szTmpPng.c_str()); } #endif // remove the temp file (that lacks proper extension) remove(szTempFileName); g_free (szTempFileName); szTempFileName = NULL; // // Get the initial file status. // struct stat myFileStat; int ok = stat(szTmp.c_str(),&myFileStat); if(ok < 0) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); remove(szTmpPng.c_str()); remove(szTmp.c_str()); // should silently fail if exporting as PNG file return false; } time_t mod_time = myFileStat.st_mtime; // // Fire up the image editor... // ProcessInfo procInfo; if (!createChildProcess(imageApp.c_str(), szTmp.c_str(), &procInfo)) { UT_String msg = "Unable to run program: "; msg += imageApp + " " + szTmp; pFrame->showMessageBox(msg.c_str(), XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); // failed to spawn stuff, so do some cleanup and return failure remove(szTmpPng.c_str()); remove(szTmp.c_str()); // should silently fail if exporting as PNG file return false; } lockGUI(d); while (isProcessStillAlive(procInfo)) { UT_usleep(10000); // wait 10 milliseconds pFrame->nullUpdate(); ok = stat(szTmp.c_str(),&myFileStat); if(ok == 0) { if(myFileStat.st_mtime != mod_time) { // wait for changes to settle (program done writing changes) // we use both modified time & file size, but really we // could just use file size as mod time doesn't appear to change for small images mod_time = myFileStat.st_mtime; off_t size = myFileStat.st_size; UT_usleep(100000); // wait 100 milliseconds (so program may have time to write something) ok = stat(szTmp.c_str(),&myFileStat); while((mod_time != myFileStat.st_mtime) || !size || (size > 0 && size != myFileStat.st_size)) { mod_time = myFileStat.st_mtime; size = myFileStat.st_size; ok = stat(szTmp.c_str(),&myFileStat); UT_usleep(500000); // wait a while, let program write its data // just make sure the program is still running, otherwise we could get stuck in a loop if (!isProcessStillAlive(procInfo)) { pFrame->showMessageBox("External image editor appears to have been terminated unexpectedly.", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); //procInfo.hProcess = 0; goto Cleanup; } } mod_time = myFileStat.st_mtime; UT_usleep(100000); // wait a while just to make sure program is done with file // // OK replace the current image with this. // IEGraphicFileType iegft = IEGFT_Unknown; FG_Graphic* pFG; UT_Error errorCode; #ifdef ENABLE_BMP // // Convert bmp back to png (as we can not assume AbiWord has builtin BMP support [as its now an optional plugin]) // NOTE: probably looses detail/information though!!! so if possible use only PNG // if (!bLeaveImageAsPNG) { if (convertBMP2PNG(szTmp.c_str(), szTmpPng.c_str())) { pFrame->showMessageBox("Unable to convert BMP image data back to PNG for AbiWord to import!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); UT_ASSERT(UT_SHOULD_NOT_HAPPEN); goto Cleanup; } } #endif errorCode = IE_ImpGraphic::loadGraphic(szTmpPng.c_str(), iegft, &pFG); if(errorCode) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); pFrame->showMessageBox("Error making pFG. Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); goto Cleanup; } unlockGUI(d); pView->cmdUnselectSelection(); pView->setPoint(pos); pView->extSelHorizontal(true, 1); // move point forward one errorCode = pView->cmdInsertGraphic(pFG); if (errorCode) { pFrame->showMessageBox("Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK); UT_ASSERT(UT_SHOULD_NOT_HAPPEN); DELETEP(pFG); goto Cleanup; } DELETEP(pFG); // // Reselect the image // pView->setPoint(pos); pView->extSelHorizontal(true, 1); // move point forward one lockGUI(d); } } } // // Normal exit, delete the tempfile and return success // remove(szTmpPng.c_str()); remove(szTmp.c_str()); // should silently fail if exporting as PNG file unlockGUI(d); return true; // // Something went wrong. // Cleanup: remove(szTmpPng.c_str()); remove(szTmp.c_str()); // should silently fail if exporting as PNG file unlockGUI(d); // // Kill the image editor. // endProcess(procInfo); return false; }