C program in Linux, signal handlers - c

I am trying to understand basic signals concepts so I can write a program that handles every possible signal printing its id on the screen.
I don’t know what means every possible signals. I have read that we can get all signals handled by system using kill -l commands so do I understand it properly that I should write a program that handles all those 64 signals? I’ve also read that some signals can be sent to the process by keyboard shortcuts but How many signals are there that are sent in that way - I managed to find only Ctrl-C, Ctrl-Z, Ctrl-. So How to send the rest of the signals to program if there are no shortcuts for the rest of the signals? I can’t get over It for whole day long, asking in forum was my last step I took, Not the first one.

Related

How does a Unix program like bc cleanly handle input/ouput stream when started as a background job?

I noticed that the Unix bc program does not print out it's usual prompt (the three symbols ">>> ") when being started as a background process (like if you execute it as "bc &"). This is confusing to me because from my limited knowledge of Unix, starting a program as a background job will keep it running until as soon as it tries to read from stdin, at which point it will receive a signal to stop itself.
But running bc as a background job ("bc &") will not cause it to at least print out the ">>> " prompt before stopping itself which tells me that the program handles that somehow. I am curious as to how it does this. When I wrote a naive program that only tries to emulate the input/output interaction, it still prints out ">>> " before being suspended which doesn't look very clean at all and the behavior gets even more bizarre on certain shells.
I tried looking through the Unix bc source code and I was able to trace the code to parts where it is printing out the ">>> " prompt, but how it was handling not printing out the prompt when started as a background process was beyond me. And I know that obviously you would never start an input/output interactive program in the background as that goes against intended functionality and common sense, but I am more interested in the concepts behind it like if this was implemented with signal handling and/or if this is some more advanced input/output stream buffering or some other Unix concept that I am not familiar with.
The first thing your version of bc does is call the tcsetattr function. This function, when called from a background process, causes the SIGTTOU signal to be sent to the process, which by default causes the process to stop.
Any program that manipulates terminal attributes (vim, bash, anything that uses readline or curses, ...) will probably behave exactly the same way.

Signal Handling Output Display Issue

I am creating a relatively simple multiple process program to learn about signals and signal handling in Linux using C. I have several processes handling signals (I use sigaction to assign handlers) that are sent to all processes in the process group and one tracking process that displays some information after a certain number of signals are detected.
My question is this. How do I reliably display console output from the tracking process? This process needs to display the current number of signals detected and I know printf() isn't good to call from a signal handler. I know I can use write(), but I am not sure I can put variable values into this to display, and I think this system call can be interrupted by signals.
Could you give me a simple example with 3 processes (one generating the signal (parent), 1 handling the signal (child 1) and one reporting info on the signals (child 2)), or explain how this reporter process should handle the output with values of global shared variables?
Thanks
See How to avoid using printf() in a signal handler? for some information about what can be done in a signal handler.
I can't give you a 'simple' example for your 3 process request because the scenario you outline is incredibly complex — how on earth is the third process going to know about what signals the first process sent to the second process? Signals are very crude; there is very little information available other than 'a signal was sent' (slightly more if you use the sa_sigaction member of the struct sigaction and SA_SIGINFO flag when calling the sigaction() function). For most practical purposes, what you ask for can't be done.
If you're going to get close to your scenario, then maybe the method is to set up a shared memory segment in the parent which both children have access to. The second child (signal receiver) can then copy information into the shared memory when it receives a signal, while the third child copies the information out of shared memory and writes it. You'll need to look to see what coordinating functions (if any) are available to a signal handler function — the x-ref'd question has answers which cover this point (and the answer looks like 'none', or only crude ones like open() or mkdir()). Curiously, the POSIX standard does not list function such as strcpy() or memcpy() as signal-safe.
As to 'how to reliably display console output', what is your process going to do while waiting for signals to arrive? You can arrange for the signal handler to set a flag, and the looping code can arrange to check the flag, format and write the data (with standard I/O even; this isn't in a signal handler any more), before going back to waiting for the next signal to arrive.

Writing and reading from terminal using pthreads

I want to create a multithreaded application in C using pthreads. I want to have a number of worker threads doing stuff in the background, but every once in a while, they will have to print something to the terminal so I suppose they will have to
"acquire the output device" (in this case stdout)
write to it
release the output device
rinse and repeat.
Also, I want the user to be able to "reply" to the output. For the sake of simplicity, I'm going to assume that nothing new will be written to the terminal until the user gives an answer to a thread's output, so that new lines are only written after the user replies, etc. I have read up on waiting for user input on the terminal, and it seems that ncurses is the way to go for this.
However, now I have read that ncurses is not thread-safe, and I'm unsure how to proceed. I suppose I could wrap everything terminal-related with mutexes, but before I do that I'd like to know if there's a smarter and possibly more convenient way of going about this, maybe a solution with condition variables? I'm somewhat lost here, so any help is welcome.
Why not just have a thread whose job is to interact with the terminal?
If other threads want to send message or get replies from the terminal, they can create a structure reflecting that request, acquire a mutex, and add that structure to a linked list if structures. The terminal thread will walk the linked list, outputting data as needed and getting replies as needed.
You can use a condition variable to signal the terminal thread that there's now data that needs to be output. The structure in the linked list can include a response condition variable that the terminal thread can signal when it has the reply, if any.
For output that gets no reply, the terminal thread can delete the structure after it outputs its contents. For output that gets a reply, the terminal thread can signal the thread that's interested in the output and then let that thread delete the structure once it has copied the output.
You can use fprintf on terminal. fprintf takes care of the concurrency issues, like it will use mutex locks on stdout before writing to the output device.

Uninterruptable process in Windows(or Linux)?

Is there any way to make a program that cannot be interrupted (an uninterrupted program)? By that, I mean a process that can't be terminated by any signal, kill command, or any other key combinations in any System: Linux, windows etc.
First, I am interested to know whether it's possible or not. And if yes, upto what extend it is possible?
I mostly write code in C, C++, and python; but I don't know any of such command(s) available in these programming languages.
Is it possible with assembly language, & how ? Or in high level language c with embedded assembly code(inline assembly)?
I know some signals are catchable some are not like SIGKILL and SIGSTOP.
I remember, when I was use to work on Windows-XP, some viruses couldn't be terminated even from Task Manager. So I guess some solution is possible in low level languages. maybe by overriding Interrupt Vector Table.
Can we write an uninterrupted program using TSRs(Hooking)? Because TSR can only removed when the computer is rebooted or if the TSR is explicitly removed from memory. Am I correct?
I couldn't find any thing on Google.
Well, possibly one can write a program which doesn't respond for most signals like SIGQUIT, SIGHUP etc. - each kind of "kill" is actually a kind of signal sent to program by kernel, some signals means for the kernel that program is stuck and should be killed.
Actually the only unkillable program is kernel itself, even init ( PID 1 ) can be "killed" with HUP ( which means reload ).
Learn more about signal handling, starting with kill -l ( list signals ) command.
Regarding Windows ( basing on "antivirus" tag ) - which actually applies to linux too - if you just need to run some antivirus user is unable to skip/close, it's permission problem, I mean program started by system, and non-administrative user without permission to kill it, won't be able to close/exit it anyway. I guess lameusers on Windows all over the world would start "solving" any problems they have by trying to close antivirus first, just if it would be possible :)
On Linux, it is possible to avoid being killed by one of two ways:
Become init (PID 1). init ignores all signals that it does not catch, even normally unblockable ones like SIGSTOP and SIGKILL.
Trigger a kernel bug, and get your program stuck in D (uninterruptible wait) state.
For 2., one common way to end up in D state is to attempt to access some hardware that is not responding. Particularly on older versions of Linux, the process would become stuck in kernel mode, and not respond to any signals until the kernel gave up on the hardware (which can take quite some time!). Of course, your program can't do anything else while it's stuck like this, so it's more annoying than useful, and newer versions of Linux are starting to rectify this problem by dividing D state into a killable state (where SIGKILL works) and an unkillable state (where all signals are blocked).
Or, of course, you could simply load your code as a kernel module. Kernel modules can't be 'killed', only unloaded - and only if they allow themselves to be unloaded.
You can catch pretty-much any signal or input and stay alive through it, the main exception being SIGKILL. It is possible to prevent that from killing you, but you'd have to replace init (and reboot to become the new init). PID 0 is special on most Unixes, in that it's the only thing that can't be KILL'd.

Exiting gracefully from a multithreaded process

I'm running a multi-threaded C program (process?) , making use of semaphores & pthreads. The threads keep interacting, blocking, waking & printing prompts on stdout continuously, without any human intervention. I want to be able to exit this process (gracefully after printing a message & putting down all threads, not via a crude CTRL+C SIGINT) by pressing a keyboard character like #.
What are my options for getting such an input from the user?
What more relevant information could I provide that will help to solve this problem?
Edit:
All your answers sound interesting, but my primary question remains. How do I get user input, when I don't know which thread is currently executing? Also, semaphore blocking using sem_wait() breaks if signalled via SIGINT, which may cause a deadlock.
There is no difference in reading standard input from threads except if more than one thread is trying to read it at the same time. Most likely your threads are not all calling functions to read standard input all the time, though.
If you regularly need to read input from the user you might want to have one thread that just reads this input and then sets flags or posts events to other threads based on this input.
If the kill character is the only thing you want or if this is just going to be used for debugging then what you probably want to do is occasionally poll for new data on standard input. You can do this either by setting up standard input as non-blocking and try to read from it occasionally. If reads return 0 characters read then no keys were pressed. This method has some problems, though. I've never used stdio.h functions on a FILE * after having set the underlying file descriptor (an int) to non-blocking, but suspect that they may act odd. You could avoid the use of the stdio functions and use read to avoid this. There is still an issue I read about once where the block/non-block flag could be changed by another process if you forked and exec-ed a new program that had access to a version of that file descriptor. I'm not sure if this is a problem on all systems. Nonblocking mode can be set or cleared with a 'fcntl' call.
But you could use one of the polling functions with a very small (0) timeout to see if there is data ready. The poll system call is probably the simplest, but there is also select. Various operating systems have other polling functions.
#include <poll.h>
...
/* return 0 if no data is available on stdin.
> 0 if there is data ready
< 0 if there is an error
*/
int poll_stdin(void) {
struct pollfd pfd = { .fd = 0, .events = POLLIN };
/* Since we only ask for POLLIN we assume that that was the only thing that
* the kernel would have put in pfd.revents */
return = poll(&pfd, 1, 0);
}
You can call this function within one of your threads until and as long as it retuns 0 you just keep on going. When it returns a positive number then you need to read a character from stdin to see what that was. Note that if you are using the stdio functions on stdin elsewhere there could actually be other characters already buffered up in front of the new character. poll tells you that the operating system has something new for you, not what C's stdio has.
If you are regularly reading from standard input in other threads then things just get messy. I'm assuming you aren't doing that (because if you are and it works correctly you probably wouldn't be asking this question).
You would have a thread listening for keyboard input, and then it would join() the other threads when receiving # as input.
Another way is to trap SIGINT and use it to handle the shutdown of your application.
The way I would do it is to keep a global int "should_die" or something, whose range is 0 or 1, and another global int "died," which keeps track of the number of threads terminated. should_die and died are both initially zero. You'll also need two semaphores to provide mutex around the globals.
At a certain point, a thread checks the should_die variable (after acquiring the mutex, of course). If it should die, it acquires the died_mutex, ups the died count, releases the died_mutex, and dies.
The main initial thread periodically wakes up, checks that the number of threads that have died is less than the number of threads, and goes back to sleep. The main thread dies when all the other threads have checked in.
If the main thread doesn't spawn all the threads itself, a small modification would be to have "threads_alive" instead of "died". threads_alive is incremented when a thread forks, and decremented when the thread dies.
In general, terminating a multithreaded operation cleanly is a pain in the butt, and besides special cases where you can use things like the semaphore barrier design pattern, this is the best I've heard of. I'd love to hear it if you find a better, cleaner one.
~anjruu
In general, I have threads waiting on a set of events and one of those events is the termination event.
In the main thread, when I have triggered the termination event, I then wait on all the threads having exited.
SIGINT is actually not that difficult to handle and is often used for graceful termination. You need a signal handler and a way to tell all the threads that it's time to stop. One global flag that threads check in their loops and the signal handler sets might do. Same approach works for "on user command" termination, though you need a way to get the input from the terminal - either poll in a dedicated thread, or again, set the terminal to generate a signal for you.
The tricky part is to unblock waiting threads. You have to carefully design the notification protocol of who tells who to stop and what they need to do - put dummy message into a queue, set a flag and signal a cv, etc.

Resources