-1

I want to send SIGINT to a program started using QProcess.

I am working on ubuntu.

Source code of my process looks like this:

#include <iostream>
#include <csignal>
#include <stdlib.h>
#include <unistd.h>

void int_handle(int sig)
{
   std::cout<<"Received SIGINT\n";
   exit(0);
}

int main()
{
    std::cout<<"Main called\n";
    signal(SIGINT, int_handle);
    while(1)
    {
        std::cout<<"Sleeping.....\n";
        sleep(1);
    }

    return 0;
}

Compiled this program and generated executable my_prog my Qprocess looks as shown below

QProcess* process= new Qprocess();
QString command = "my_prog";
process->start(command);
process->waitForStarted();

Based on some event I tried sending SIGINT in following ways

process->kill();
process->close();
process->write("0x03");
process->terminate();
kill(process->pid(), SIGINT);

QString command = kill -9 <PID>;
QByteArray ba = command.toLatin1();
system(ba.data());

Even after trying all these things I am not able to receive the SIGINT in my program.

Please help me in finding the correct way to implement this.

EDIT1: Updated the example program. I tried to explain the problem and ignored syntax errors in the example. Sorry for that.

Thanks in advance.

mkreddy
  • 163
  • 3
  • 5
  • 12
  • What makes you think the process didn't receive the `SIGINT`? – G.M. Jan 02 '18 at 14:41
  • 2
    That `main()` will end by itself instantly. – Velkan Jan 02 '18 at 14:45
  • Are you sure the sub-process is starting successfully? Could you put a debug statement in the my_prog main() to test? – Joshua Fraser Jan 02 '18 at 16:38
  • 1
    Your code contains several syntax errors and is gernerally incomplete, it will not compile. You're supposed to provide an [mcve] if you expect useful answers. – Murphy Jan 02 '18 at 17:51
  • @JoshuaFraser I am able to the see debug statement from main(). @Murphy Here I am able to see the debug statement from `int_handle` when I ran the program from terminal. I am not able to see the same when I ran the program from QProcess. – mkreddy Jan 03 '18 at 04:45
  • And the current code paints a different picture; that's exactly why you're supposed to provide a MCVE - which isn't there yet, the other code still contains the same bugs. Thus it's still unclear which code you tested with, and pointing out problems is more a view into the crystal ball. – Murphy Jan 03 '18 at 10:31
  • 1
    BTW, you won't see output on the console from a program started with `QProcess`, as `stdin`, `stdout` and `stderr` are redirected. I suggest you first start reading the [docs](http://doc.qt.io/qt-5/qprocess.html#communicating-via-channels), then build a [mcve], and then come back if there are still questions left. – Murphy Jan 03 '18 at 10:34

2 Answers2

1

Besides from several syntax errors/typos in your example, which will prevent the code from even compiling, the program which you try to kill has two and a half issues:

  1. The signal handler has the wrong signature, it receives an integer parameter as shown in the manpage. This won't even compile with g++.
  2. In main no event loop or similar is started. Thus when you execute the binary, it registers the signal handler, and exits immediately after that, because signal() is non-blocking.
  3. From the signal() manpage:

    Avoid its use: use sigaction(2) instead.

Edit

Point 1 and 2 are obsoleted by EDIT1 of OP, point 3 remains.

Murphy
  • 3,827
  • 4
  • 21
  • 35
1

As pointed out by Murphy, QProcess captures stdout/stderr and makes it available through a QIODevice interface. If you don't forward the subprocess output to the parent process, you won't see any output.

After forwarding the process channels, you must also send the correct signal if you want your signal handler to be called. The process->kill() sends a SIGKILL not a SIGINT, so your signal handler wouldn't be invoked. Most of your examples for killing the subprocess are sending the wrong signal.

Finally, be sure that your command is actually starting. I had to specify a relative local path ./my_prog in order to have the process start successfully.

Here is some code based on your incomplete example that works for me:

#include <QProcess>
#include <QDebug>
#include <unistd.h>
#include <csignal>

int main(int argc, char *argv[])
{
  QProcess *process = new QProcess();

  // Start process from local directory
  QString command = "./my_prog";

  // Forward output of process to parent stdout/stderr
  process->setProcessChannelMode(QProcess::ForwardedChannels);
  process->start(command);

  // Ensure process starts successfully; wait indefinitely
  if(process->waitForStarted(-1))
  {
    qDebug() << "Process started.";

    // Wait a little before sending signal
    sleep(1);

    // Send the correct signal
    kill(process->pid(), SIGINT);

  } else {
    qDebug() << "Failed to start process.";
  }
}
Joshua Fraser
  • 356
  • 1
  • 3
  • 6