How do I replace the default SIGINT handler when using sigaction? - unix

I've been playing with sigaction in the nix-rust crate to try and handle a SIGINT signal in my program and instead do nothing. While I've been able to handle the signal using:
let sig_action = signal::SigAction::new(
handle_signal,
signal::SockFlag::empty(),
signal::SigSet::empty()
);
unsafe { signal::sigaction(signal::SIGINT, &sig_action); }
It seems no matter what I do in the handle_signal function, when it concludes, the SIGINT is still processed and the program exits. My handler does not replace the default functionality, rather it happens before it. What would the function have to do to instead prevent the interrupt from still causing the program to exit?

Are you using cargo run to run your program? If so, it sounds like your program is handling the SIGINT signal and instead cargo is being killed. Since cargo doesn't have any special handling it is being killed by the signal, thus ending your program.

Related

kill a process without raising error with qt

I need to kill a process without raising any errors. I need to make distinction between when the process crashed and when the user killed it intentionally. I see that on Windows a command line process can be closed only using .kill() and not .terminate().
If I connect the .errorOccurred(), the function is called even if I intentionally press the button to kill the process. Is there a way to avoid this?
There is QObject::blockSignals(), which temporarily prevents any signal from being emitted.
However, I would avoid using it, and handle it instead in the code that is handling the process.
Two options:
Disconnect the process’ signals before terminating:
m_process.disconnect(this);
m_process.kill();
Remember that you’re in “killing state” and ignore the signal/handle it differently:
m_killingProcess = true; // member variable defaulting to false
m_process.kill();
In the slot connected to errorOccurred:
void Foo::processErrorOccurred(QProcess::ProcessError error)
{
if (m_killingProcess) {
// do nothing?
return;
}
// handle process error (when not killing)
}

How to know when process gets killed in unix

I am working on an Spark project which has an executable which starts the process in background , now I need to know when the process gets killed through Bash.The only solution I got is to continuously check its PID existence through grep in loop if exist or not , Is there any other possible solution that do it without looping around .
I also tried handling the exit codes ,but the exit code is 0 if process runs and only changes when it gets killed which need to be checked continuously
If I understand right, the situation is this:
Your executable does somewhere fork and run another logic in another process, and you want the main process to get notify whether the forked process is still running.
In order to answer I'll make sure we both are familiar with the same terminology:
The main process (when you run your executable) is called the parent process.
The process that the parent process is starting, is called the child process.
Now when a child process dies a signal SIGCHLD is sent to the parent process, Normally SIGCHLD is mapped to SIG_DFL which is actually SIG_IGN for SIGCHLD. In human words, it means that the parent process does not give a shit if the child process dies.
But, If you want to get notify, you may change the behaviour of what happens when SIGCHLD is sent. In order to do so you must implement signal handler function:
void custom_sigchld_handler(int sig)
{
pid_t p;
int status;
while ((p = waitpid(-1, &status, WNOHANG)) != -1)
{
// If you got here it means p is a dead process. Do your logic here...
}
}
Then you must declare that you want our custom_sigchld_handler to take care of SIGCHLD signals:
struct sigaction signal_action = {0};
signal_action.sa_handler = custom_sigchld_handler;
sigaction(SIGCHLD, &signal_action, NULL);
May need a little more context... if your executable is starting the process, there is surely a way to get or keep a handle on it while executing.
In php, there is proc_open(), in Qt there is the QProcess class, in c/c++, there is popen()
Many languages have this feature, but without more details it's hard to offer a solution.

how to pause the program for some seconds?

I want to pause my program for some seconds in a program that i'm writing by c++ Qt.in fact when the program arrive to one of my functions it stops for for example 5 seconds and then continue next lines.what should I do?
that function is a member function of a class and I want to o that work(pausing)for each instance of the class...
In case you really need to do that, you have several options
You can use QThread's sleep methods by inheriting QThread and making them public (those are protected because it's generally a bad idea)
Or you can use QEventLoop exec together with QTimer. Connect timer's signal to QEventLoop's quit() slot. That will cause "non-blocking" wait, so your app will not stay frozen.
Or maybe you should instead split your code into two methods, make the second one a slot and call it with a timer when appropriate
EDIT: something like, in your eat method you use QTimer::singleShot to call finishEating slot after X seconds.
You might also want to read this: http://qt-project.org/doc/qt-5.0/qtcore/thread-basics.html
If you are using Qt5 you can use the following trick:
QMutex mut;
mut.lock();
mut.tryLock(milliseconds);
mut.unlock(); // I am not sure if this is a necessity
With Qt4 you can use QWaitCondition::wait() on the mutex;
Keep in mind that if this is in your interface thread your gui will freeze until the interval ellapses.

interrupted system call error when writing to a pipe

In my user space Linux application, I have a thread which communicated to the main process through a pipe. Below is the code
static void _notify_main(int cond)
{
int r;
int tmp = cond;
r = write( _nfy_fd, &tmp, sizeof(tmp) );
ERROR( "write failed: %d. %s\n", r, strerror(r) );
}
Pretty straight forward. It's been working fine for quite a while now. But recently, the write call will fail with "interrupted system call" error after the programme went under some stress test.
Strangely, the stuff actually went through the pipe no problem. Of course I'd still like to go to the bottom of the error message and get rid of it.
Thanks,
The write(2) man page mentions:
Conforming to
SVr4, 4.3BSD, POSIX.1-2001.
Under SVr4 a write may be interrupted and return EINTR at any point, not just before any data is written.
I guess you were just lucky that it didn't occur so far.
If you google just for the "interrupted system call", you will find this thread which tells you to use siginterrupt() to auto-restart the write call.
From http://www.gnu.org/
A signal can arrive and be handled while an I/O primitive such as open
or read is waiting for an I/O device. If the signal handler returns,
the system faces the question: what should happen next?
POSIX specifies one approach: make the primitive fail right away. The
error code for this kind of failure is EINTR. This is flexible, but
usually inconvenient. Typically, POSIX applications that use signal
handlers must check for EINTR after each library function that can
return it, in order to try the call again. Often programmers forget to
check, which is a common source of error.
So you can handle the EINTR error, there is another choice by the way, You can use sigaction to establish a signal handler specifying how that handler should behave. Using the SA_RESTART flag, return from that handler will resume a primitive; otherwise, return from that handler will cause EINTR.
see interrupted primitives

Restore serial port attributes even after control-C?

When using a serial port via POSIX, it's recommended to save the original attributes using tcgetattr() before changing them with tcsetattr(), and then restore them before closing the port. What about when a program is terminated by pressing control-C or when the program receives SIGINT? I haven't seen this covered in any of the serial tutorials.
Apparently an atexit() function wouldn't be sufficient, because it's not called by the default SIGINT handler. So it seems installation of a signal handler would be necessary that restores the attributes to any serial ports still open. Is it even safe to call tcsetattr() from a signal handler?
One might simply dismiss this issue as insignificant, but it's common to terminate a program with control-C, especially one that can take tens of seconds to complete operations. If it's OK not to preserve serial port settings in this case, then there seems little reason to preserve them at all. If anything, it might be better not to bother, rather than do it inconsistently.
I found some examples of source code doing the above, but nothing well-documented. I guess I'm interested in some discussion of whether this is a good idea. Thanks.
After further research I think I've answered this to my satisfaction.
First, in the man page for signal I noticed that a signal handler is specifically allowed to call tcsetattr(), along with a few others:
The signal handler routine must be very careful, since processing elsewhere was interrupted at some arbitrary point. POSIX has the concept of "safe function". If a signal interrupts an unsafe function, and handler calls an unsafe function, then the behavior is undefined. Safe functions are listed explicitly in the various standards. The POSIX.1-2003 list is ... `raise()` ... `signal()` ... `tcsetattr()` [trimmed to relevant ones]
This strongly suggests that the POSIX committee had this exact kind of thing in mind, and leads to a straight forward approach where you change the SIGINT handler once you've opened serial and saved its attributes, then in your handler, restore them and the old SIGINT handler, then re-raise the signal:
static void (*prev_sigint)( int );
static termios saved_attr;
static int fd;
static void cleanup( int ignored )
{
tcsetattr( fd, TCSANOW, &saved_attr );
signal( SIGINT, prev_sigint );
raise( SIGINT );
}
int main( void )
{
open_serial_and_save_attrs();
prev_sigint = signal( SIGINT, cleanup );
...
}

Resources