How to pause until signal and not have C print? - c

I'm guessing I need to call some function in my signal handler and I have no idea what it is
My program wants to sleep until it receives some kind of signal. So naturally I used pause(). Now it ran just fine when I sent my app SIGUSR1 however I get a print out of User defined signal 1 which is not what I want because I plan to send many signals and it will make the console unreadable. I tried handling the signal by writing signal(SIGUSR1, mySignalHandler); but now pause() no longer resumes after I receive the signal. Is there some kind of function I need to call from mySignalHandler?

The default behavior when a program receive a USR1 signal is to terminate (see https://www.man7.org/linux/man-pages/man7/signal.7.html, standard signal).
An empty signal handle will just do what you want: no message will be displayed.
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
static int s_got = 0;
void handler(int s)
{
++s_got;
}
int main(void)
{
signal(SIGUSR1, handler);
while(1) {
pause();
printf("resumed %d\n", s_got);
}
return 0;
}
:~/so/pause$ gcc -Wall main.c
:~/so/pause$ ./a.out &
[1] 2286
:~/so/pause$ pkill -USR1 a.out
resumed 1
:~/so/pause$ pkill -USR1 a.out
resumed 2
:~/so/pause$ pkill -USR1 a.out
resumed 3
:~/so/pause$ pkill -USR1 a.out
resumed 4
:~/so/pause$ pkill -USR1 a.out
resumed 5
:~/so/pause$

Related

Why is my thread function running twice?

#include <stdio.h>
#include <sys/wait.h>
#include <pthread.h>
void* runfunc(void* arguments){
printf("in run thread\n");
return NULL;
}
int main(void)
{
pthread_t pthread_id;
pthread_create(&pthread_id, NULL, runfunc, NULL);
printf("after pthread creation\n");
return 0;
}
$ gcc -pthread intro.c
$ ./a.out
after pthread creation
in run thread
in run thread
$ ./a.out
after pthread creation
$
There are 4 types of outputs for this program on linux.
"after pthread creation" -> this output can be easily understood as before thread execution process completes and exits and deletes all threads.
"after pthread creation
in " -> this output can also be understood as while process was exiting thread executed a little bit to print in
"in running thread
after pthread creation" -> this output can also be easily understood
"after pthread creation
in running thread
in running thread" -> now i don't get why am i getting "in running thread" 2 times instead of once.
Linux implementation of threads is considered.

SIGUSR1 in Linux

Please help my SIGUSR1 is not being received and I do not know what is wrong. I am doing this for practice in Linux. I exit the process in using ctrl+z and then type in kill -SIGUSR1 but the signal is not being received.
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
void sig_handler(int signo){
switch(signo)
case SIGUSR1:
printf("Hello\n");
exit(0);
}
int main()
{
pid_t pid;
printf("PID: %i\n", getpid());
while(1)
{
if(signal(SIGUSR1, sig_handler) == SIG_ERR)
{
printf("Error\n");
}
sleep(2);
}
return 0;
}
Try these steps
step 1 : run in background
bash# ./a.out &
[1] 4338
# PID: 4338
step 2: issue SIGUSR1 from bash to the pid
bash# kill -10 4338
10 is for SIGUSR1
Pressing the ctrl+z key causes the system to send a TSTP signal (SIGTSTP) to the running process and causes the process to suspend its execution.
Hence when you send kill -SIGUSR1 on suspended process, SIGUSR1 signal will be blocked.
For example:
Run the process
$ ./a.out
PID*****: 10869
Suspend the process
^Z //Pressed ctrl+z
[1]+ Stopped ./a.out
$ ps
PID TTY TIME CMD
7529 pts/0 00:00:00 bash
10869 pts/0 00:00:00 a.out
10870 pts/0 00:00:00 ps
Send SIGUSR
$ kill -SIGUSR1 10869
$
/*SIGUSR is blocked until process resumes*/
Resume the process.
$ fg
./a.out
Hello***
SIGUSR is sent to process
$ ps
PID TTY TIME CMD
7529 pts/0 00:00:00 bash
10871 pts/0 00:00:00 ps
Solution:
Use & to run your process in background and send SIGUSR1 signal as below.
$ ./a.out &
[1] 11400
$ PID*****: 11400
$kill -SIGUSR1 11400
$Hello***
$
[1]+ Done ./a.out

SIGTSTP Handler terminates both parent and child process

My Goal: I have a simple c program that should overwrite the default SIGTSTP handler with my own, and send a SIGTSTP only to the child process.
My Issue: The kill call within the SIGTSTP handler stops the parent process, and exits my program (not just the child). What am I doing wrong?
Edit: This problem seems to only happen when I compile and run my code using the following make command: gcc -o program *.c -lreadline && ./program. It seems (the make process?) is terminated because my output contains the following line upon ctrl-z:
gcc -o sandbox *.c -lreadline && ./sandbox
Is there a way to both get my program to have the desired functionality and use make?
My Code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <readline/readline.h>
int child;
void handler();
static void SIGTSTP_Handler()
{
if (child != 0) {
kill(child, SIGTSTP);
}
}
int main(void)
{
signal(SIGTSTP, SIGTSTP_Handler);
child = fork();
if (child == 0) {
setpgid(0, getpid());
printf("CHILD's PID ::: [ %d ]\n", getpid());
printf("CHILD's GROUP ::: %d\n", getpgrp());
execlp("sleep", "sleep", "30", NULL);
}
else {
setpgid(child, child);
int status;
printf("CHILD's PID (From Parent Perspective) ::: [ %d ]\n", child);
printf("PARENT's PID ::: %d\n", getpid());
printf("PARENT's GROUP ::: %d\n", getpgrp());
waitpid(child, &status, WUNTRACED | WCONTINUED);
}
while (1);
}
The issue was caused because the make command that I started my program using was terminated by ctrl-z. To fix the problem you can either:
OLD Problematic Make Command:
gcc -o program *.c && ./program
Potential Solutions:
(1) Remove the && ./program line from the make command
(2) Compile and run your program without using make
I am unsure if there is anyway to still use start the program using make if you are hoping to keep your main program running in the case of a SIGTSTP signal

pthread_cond_wait() and signal, the result depend on OS

I am a beginner of multi-threaded programming, and now I know that when a signal was sent while waiting with pthead_cond_wait(), the result depends on the OS.
Can somebody tell me how to know how the call was interrupted, and how to write portable code?
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
void
sigusr1_handler(int sig)
{
printf("signal called\n");
}
int
main()
{
int n;
pthread_mutex_t mut;
pthread_cond_t cond;
struct timespec ts;
signal(SIGUSR1, sigusr1_handler);
pthread_mutex_init(&mut, NULL);
pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&mut);
printf("before cond_wait\n");
n = pthread_cond_wait(&cond, &mut);
printf("after pthread_cond_wait : %d\n", n);
perror("error pthread_cond_wait:");
pthread_mutex_unlock(&mut);
return 0;
}
MacOS X 10.11.4
cc -o condwait condwait.c -lpthread
Linux 2.6.32-642.3.1.el6.x86_64
gcc -o condwait condwait.c -lpthread
Solaris11 5.11 11.2
cc -D_POSIX_C_SOURCE -D_REENTRANT -mt -o condwait condwait.c -lpthread
MacOS X
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait:: Unknown error: 260
Solaris
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
after pthread_cond_wait : 0
error pthread_cond_wait : Error 0
Linux
$ ./condwait &
[1] xxxxx
$ kill -USR1 %1
signal called
$ jobs
[1]+ Running
When using Solaris native cond_wait(), it returns EINTR as documented.
Is there any idea how to know that pthread_cond_wait() was interrupted?
POSIX specifies that this function will never return EINTR. For portability to legacy OSes you can check for it anyway, it doesn't hurt
More importantly, you should be prepared for spurious wakeups. The function can return zero at any time for any reason wiith the condition not being met. The mutex will be locked. You have to check the condition and, if not met, go back to pthread_cond_wait.
I read the Linux pthread_cond_wait's man manual, it says:
If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it shall return zero due to spurious wakeup.
I guess other OS's also have manuals to help you figure it out.
Thank you very much for everyone.
Now I know that with using signal to stop long waiting condition do not work.
pthread_cond_wait() resume waiting for the condition as if it was not interrupted, or it returns zero due to spurious wakeup.
Then I want to do that, I will need a second lock like
pthread_mutex_lock(&mut);
while(condition_is_false) {
n = pthread_cond_timedwait();
if (n == ETIMEDOUT) {
pthread_mutex_lock(&mut2);
if (condition2_is_true) {
pthread_mutex_unlock(&mut2);
pthread_mutex_unlock(&mut);
return STOPPED;
}
pthread_mutex_unlock(&mut2);
}
}
pthread_mutex_unlock(&mut);
return 0;
Regards,

Why does a seccomp process always get killed?

Why does a process that has gone into seccomp mode always get killed on exit?
$ cat simple.c
#include <stdio.h>
#include <stdlib.h>
#include <linux/prctl.h>
int main( int argc, char **argv )
{
printf("Starting\n");
prctl(PR_SET_SECCOMP, 1);
printf("Running\n");
exit(0);
}
$ cc -o simple simple.c
$ ./simple || echo "Returned $?"
Starting
Running
Killed
Returned 137
From the man page, under PR_SET_SECCOMP, the only allowed system calls are read, write, exit, and sigreturn.
When you call exit(0) in the standard library (in recent Linux), you call the exit_group system call, not exit. This is not allowed, so you get a SIGKILL.
(You can see this if you strace the process...)

Resources