Diff of /gtk/SciTEGTK.cxx [d4dacf] .. [96dcfd]  Maximize  Restore

  Switch to unified view

a/gtk/SciTEGTK.cxx b/gtk/SciTEGTK.cxx
...
...
486
    // Control of sub process
486
    // Control of sub process
487
    FilePath sciteExecutable;
487
    FilePath sciteExecutable;
488
    int icmd;
488
    int icmd;
489
    int originalEnd;
489
    int originalEnd;
490
    int fdFIFO;
490
    int fdFIFO;
491
    int pidShell;
491
    GPid pidShell;
492
    bool triedKill;
492
    bool triedKill;
493
    int exitStatus;
493
    int exitStatus;
494
    guint pollID;
494
    guint pollID;
495
    int inputHandle;
495
    int inputHandle;
496
    GIOChannel *inputChannel;
496
    GIOChannel *inputChannel;
...
...
746
    void Run(int argc, char *argv[]);
746
    void Run(int argc, char *argv[]);
747
    void ProcessExecute();
747
    void ProcessExecute();
748
    virtual void Execute();
748
    virtual void Execute();
749
    virtual void StopExecute();
749
    virtual void StopExecute();
750
    static int PollTool(SciTEGTK *scitew);
750
    static int PollTool(SciTEGTK *scitew);
751
  static void ChildSignal(int);
751
  static void ReapChild(GPid, gint, gpointer);
752
    virtual bool PerformOnNewThread(Worker *pWorker);
752
    virtual bool PerformOnNewThread(Worker *pWorker);
753
    virtual void PostOnMainThread(int cmd, Worker *pWorker);
753
    virtual void PostOnMainThread(int cmd, Worker *pWorker);
754
    static gboolean PostCallback(void *ptr);
754
    static gboolean PostCallback(void *ptr);
755
    // Single instance
755
    // Single instance
756
    void SetStartupTime(const char *timestamp);
756
    void SetStartupTime(const char *timestamp);
...
...
2594
#endif
2594
#endif
2595
    scitew->ContinueExecute(FALSE);
2595
    scitew->ContinueExecute(FALSE);
2596
    return TRUE;
2596
    return TRUE;
2597
}
2597
}
2598
2598
2599
int xsystem(const char *s, int fh) {
2599
void SciTEGTK::ReapChild(GPid pid, gint status, gpointer user_data) {
2600
  int pid = 0;
2600
  SciTEGTK *self = reinterpret_cast<SciTEGTK*>(user_data);
2601
  if ((pid = fork()) == 0) {
2601
2602
      for (int i=getdtablesize();i>=0;--i) if (i != fh) close(i);
2602
  self->exitStatus = status;
2603
      if (open("/dev/null", O_RDWR) >= 0) { // stdin
2603
  self->pidShell = 0;
2604
          if (dup(fh) >= 0) { // stdout
2604
  self->triedKill = false;
2605
              if (dup(fh) >= 0) { // stderr
2605
2606
                  close(fh);
2606
  g_spawn_close_pid(pid);
2607
}
2608
2609
static void SetupChild(gpointer) {
2610
  dup2(1, 2);
2607
                 setpgid(0, 0);
2611
    setpgid(0, 0);
2608
                  execlp("/bin/sh", "sh", "-c", s, static_cast<char *>(NULL));
2609
              }
2610
          }
2611
      }
2612
      _exit(127);
2613
  }
2614
  close(fh);
2615
  return pid;
2616
}
2612
}
2617
2613
2618
void SciTEGTK::Execute() {
2614
void SciTEGTK::Execute() {
2619
    if (buffers.SavingInBackground())
2615
    if (buffers.SavingInBackground())
2620
        // May be saving file that should be used by command so wait until all saved
2616
        // May be saving file that should be used by command so wait until all saved
...
...
2639
    if (jobQueue.jobQueue[icmd].directory.IsSet()) {
2635
    if (jobQueue.jobQueue[icmd].directory.IsSet()) {
2640
        jobQueue.jobQueue[icmd].directory.SetWorkingDirectory();
2636
        jobQueue.jobQueue[icmd].directory.SetWorkingDirectory();
2641
    }
2637
    }
2642
2638
2643
    if (jobQueue.jobQueue[icmd].jobType == jobShell) {
2639
    if (jobQueue.jobQueue[icmd].jobType == jobShell) {
2644
      if (fork() == 0)
2640
      const gchar *argv[] = { "/bin/sh", "-c", jobQueue.jobQueue[icmd].command.c_str(), NULL };
2645
          execlp("/bin/sh", "sh", "-c", jobQueue.jobQueue[icmd].command.c_str(),
2641
      g_spawn_async(NULL, const_cast<gchar**>(argv), NULL, G_SPAWN_DEFAULT, NULL, NULL, NULL, NULL);
2646
              static_cast<char *>(NULL));
2647
      else
2648
         ExecuteNext();
2642
        ExecuteNext();
2649
    } else if (jobQueue.jobQueue[icmd].jobType == jobExtension) {
2643
    } else if (jobQueue.jobQueue[icmd].jobType == jobExtension) {
2650
        if (extender)
2644
        if (extender)
2651
            extender->OnExecute(jobQueue.jobQueue[icmd].command.c_str());
2645
            extender->OnExecute(jobQueue.jobQueue[icmd].command.c_str());
2652
        ExecuteNext();
2646
        ExecuteNext();
2653
    } else {
2647
    } else {
2654
      int pipefds[2];
2648
      GError *error = NULL;
2655
      if (pipe(pipefds)) {
2649
      gint fdout;
2656
          OutputAppendString(">Failed to create FIFO\n");
2650
      const char *argv[] = { "/bin/sh", "-c", jobQueue.jobQueue[icmd].command.c_str(), NULL };
2657
          ExecuteNext();
2658
          return;
2659
      }
2660
2651
2661
      pidShell = xsystem(jobQueue.jobQueue[icmd].command.c_str(), pipefds[1]);
2652
      if (!g_spawn_async_with_pipes(
2653
          NULL, const_cast<gchar**>(argv), NULL,
2654
          G_SPAWN_DO_NOT_REAP_CHILD, SetupChild, NULL,
2655
          &pidShell, NULL, &fdout, NULL, &error
2656
      )) {
2657
          OutputAppendString(">g_spawn_async_with_pipes: ");
2658
          OutputAppendString(error->message);
2659
          OutputAppendString("\n");
2660
2661
          g_error_free(error);
2662
      }
2663
      g_child_watch_add(pidShell, SciTEGTK::ReapChild, this);
2664
2665
      fdFIFO = fdout;
2662
        triedKill = false;
2666
        triedKill = false;
2663
      fdFIFO = pipefds[0];
2664
        fcntl(fdFIFO, F_SETFL, fcntl(fdFIFO, F_GETFL) | O_NONBLOCK);
2667
        fcntl(fdFIFO, F_SETFL, fcntl(fdFIFO, F_GETFL) | O_NONBLOCK);
2665
        inputChannel = g_io_channel_unix_new(pipefds[0]);
2668
        inputChannel = g_io_channel_unix_new(fdout);
2666
        inputHandle = g_io_add_watch(inputChannel, G_IO_IN, (GIOFunc)IOSignal, this);
2669
        inputHandle = g_io_add_watch(inputChannel, G_IO_IN, (GIOFunc)IOSignal, this);
2667
        // Also add a background task in case there is no output from the tool
2670
        // Also add a background task in case there is no output from the tool
2668
        pollID = g_timeout_add(20, (gint (*)(void *)) SciTEGTK::PollTool, this);
2671
        pollID = g_timeout_add(20, (gint (*)(void *)) SciTEGTK::PollTool, this);
2669
    }
2672
    }
2670
}
2673
}
...
...
4863
    g_signal_connect(G_OBJECT(IncSearchEntry), "key-press-event", G_CALLBACK(FindIncrementEscapeSignal), this);
4866
    g_signal_connect(G_OBJECT(IncSearchEntry), "key-press-event", G_CALLBACK(FindIncrementEscapeSignal), this);
4864
    Signal<&SciTEGTK::FindIncrementChanged> sigFindIncrementChanged;
4867
    Signal<&SciTEGTK::FindIncrementChanged> sigFindIncrementChanged;
4865
    g_signal_connect(G_OBJECT(IncSearchEntry),"changed", G_CALLBACK(sigFindIncrementChanged.Function), this);
4868
    g_signal_connect(G_OBJECT(IncSearchEntry),"changed", G_CALLBACK(sigFindIncrementChanged.Function), this);
4866
    g_signal_connect(G_OBJECT(IncSearchEntry),"focus-out-event", G_CALLBACK(FindIncrementFocusOutSignal), NULL);
4869
    g_signal_connect(G_OBJECT(IncSearchEntry),"focus-out-event", G_CALLBACK(FindIncrementFocusOutSignal), NULL);
4867
    gtk_widget_show(IncSearchEntry);
4870
    gtk_widget_show(IncSearchEntry);
4868
  
4871
4869
    GUI::gui_string translated = localiser.Text("Find Next");
4872
    GUI::gui_string translated = localiser.Text("Find Next");
4870
    IncSearchBtnNext = gtk_button_new_with_mnemonic(translated.c_str());
4873
    IncSearchBtnNext = gtk_button_new_with_mnemonic(translated.c_str());
4871
    table.Add(IncSearchBtnNext, 1, false, 5, 1);
4874
    table.Add(IncSearchBtnNext, 1, false, 5, 1);
4872
    g_signal_connect(G_OBJECT(IncSearchBtnNext), "clicked",
4875
    g_signal_connect(G_OBJECT(IncSearchBtnNext), "clicked",
4873
        G_CALLBACK(sigFindIncrementComplete.Function), this);
4876
        G_CALLBACK(sigFindIncrementComplete.Function), this);
...
...
5226
#ifndef GDK_VERSION_3_6
5229
#ifndef GDK_VERSION_3_6
5227
    gdk_threads_leave();
5230
    gdk_threads_leave();
5228
#endif
5231
#endif
5229
}
5232
}
5230
5233
5231
// Avoid zombie detached processes by reaping their exit statuses when
5232
// they are shut down.
5233
void SciTEGTK::ChildSignal(int) {
5234
  int status = 0;
5235
  int pid = wait(&status);
5236
  if (instance && (pid == instance->pidShell)) {
5237
      // If this child is the currently running tool, save the exit status
5238
      instance->pidShell = 0;
5239
      instance->triedKill = false;
5240
      instance->exitStatus = status;
5241
  }
5242
}
5243
5244
// Detect if the tool has exited without producing any output
5234
// Detect if the tool has exited without producing any output
5245
int SciTEGTK::PollTool(SciTEGTK *scitew) {
5235
int SciTEGTK::PollTool(SciTEGTK *scitew) {
5246
#ifndef GDK_VERSION_3_6
5236
#ifndef GDK_VERSION_3_6
5247
    ThreadLockMinder minder;
5237
    ThreadLockMinder minder;
5248
#endif
5238
#endif
...
...
5263
#ifndef NO_FILER
5253
#ifndef NO_FILER
5264
    multiExtender.RegisterExtension(DirectorExtension::Instance());
5254
    multiExtender.RegisterExtension(DirectorExtension::Instance());
5265
#endif
5255
#endif
5266
#endif
5256
#endif
5267
5257
5268
  signal(SIGCHLD, SciTEGTK::ChildSignal);
5269
5270
    // Initialise threads
5258
    // Initialise threads
5271
#if !GLIB_CHECK_VERSION(2,31,0)
5259
#if !GLIB_CHECK_VERSION(2,31,0)
5272
    g_thread_init(NULL);
5260
    g_thread_init(NULL);
5273
#endif
5261
#endif
5274
#ifndef GDK_VERSION_3_6
5262
#ifndef GDK_VERSION_3_6

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks