kprincipe
kprincipe

Reputation: 341

how can signals interrupt a system call

I was reading an article and I read the following: Suppose we want to execute an external command and wait until it exits. We don't want to wait forever, we want to set some timeout after which we will kill the child process. How to do this? To run a command we use fork(2) and execve(2). To wait for a specific process to exit we can use the waitpid(2) function, but it has no timeout parameter. We can also create a loop in which we call sleep(3) with the timeout as an argument and use the fact that sleep(3) will be interrupted by the SIGCHLD signal. This solution will work... almost. It would contain a race condition: if the process exits immediately, before we call sleep(3) we will wait until the timeout expires. It's a race similar to the one described previously. How is the system call interrupted? does the child send the signal to the parent process or the the system call sleep(3)? I don't get how the system call stop execution and passes to the parent process, is the system call like another process?

Upvotes: 1

Views: 1567

Answers (2)

Armali
Armali

Reputation: 19375

How is the system call interrupted? does the child send the signal to the parent process or the the system call sleep(3)?

When the child process executes the system call exit(2), the kernel function do_exit(), from there exit_notify() and from there do_notify_parent() is called, which sends SIGCHLD to the parent and calls __wake_up_parent().

I don't get how the system call stop execution and passes to the parent process, is the system call like another process?

The system call underlying sleep() puts the calling process in the state TASK_INTERRUPTIBLE - see e. g. Sleeping in the Kernel. After that, the process is simply not scheduled until woken up as by __wake_up_parent() above or the timeout.

Upvotes: 2

user1123335
user1123335

Reputation:

You could fork a child using gnu popen Ref gnu libc Pipe to a Subprocess .

This might help if you wanted to stop the child from being able to reset the alarm.

And then use

The alarm and setitimer functions provide a mechanism for a process to interrupt itself in the future. They do this by setting a timer; when the timer expires, the process receives a signal.

NB You would call the above before execve

Portability Note: The setitimer and getitimer functions are derived from BSD Unix, while the alarm function is specified by the POSIX.1 standard. setitimer is more powerful than alarm, but alarm is more widely used.

Ref libc Setting Alarm

You could also use timeout Ref man timeout part of coreutils

All the best

Upvotes: 1

Related Questions