Sample Header Ad - 728x90

Why does the kill command not work for SIGTSTP, but works for some other signals (SIGSTOP/SIGINT etc.)?

1 vote
2 answers
104 views
I have the following two simple programs. Parent:
package main

import (
	"fmt"
	"syscall"
)

func main() {
	attr := &syscall.ProcAttr{
		Files: []uintptr{0, 1, 2},
		Sys: &syscall.SysProcAttr{ // child in its own group
			Setpgid: true,
			Pgid:    0,
		},
	}

	_, err := syscall.ForkExec("./child/child", []string{"child"}, attr)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
}
Child:
package main

import (
	"fmt"
	"time"
)

func main() {
	for {
		fmt.Println("hi from child")
		time.Sleep(time.Second * 5)
	}
}
Output of the ps: yakog@yakog-computer:~/goprojects/parent$ ps -o pid,ppid,pgid,uid,wchan,stat,tt,command -t /dev/pts/19 PID PPID PGID UID WCHAN STAT TT COMMAND 1867701 1867320 1867701 1000 do_sel Ss+ pts/19 bash 1870508 2118 1870508 1000 ep_pol Sl pts/19 child When I press CTRL-Z or CTRL-C, it doesn't have any effect. That's exactly what I expect since the process 1870508 is not part of the foreground job and CTRL-Z/CTRL-C invokes kill -SIGTSTP -1867701/kill -SIGINT -1867701. Thus, 1870508 doesn't receive these signals. Also, when I invoke kill -SIGINT 1870508 or kill -SIGSTOP 1870508, the process is terminated/suspended. I still can understand it. Although 1870508 is not part of the foreground job, with kill command **we "directly" send the signal to the process**. However, why does kill -SIGTSTP 1870508 not work? After starting the ./parent process and calling kill -SIGTSTP 1870508 command, literally nothing happens (the 1870508 still has status R/S and continues to print to the terminal). I can't understand why it didn't suspend the process (moved it to T). It's should be same as with -SIGINT and -SIGSTOP (**we "directly" send -SIGTSTP to the process**), however, it has not effect in this case. What is strange is that if we change parent code (code below) and make it continues the execution after the child is created, then kill -SIGTSTP 1870508 works as it should (child is suspended).
package main

import (
	"fmt"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	attr := &syscall.ProcAttr{
		Files: []uintptr{0, 1, 2},
		Sys: &syscall.SysProcAttr{ // child in its own group
			Setpgid: true,
			Pgid:    0,
		},
	}

	_, err := syscall.ForkExec("./child/child", []string{"child"}, attr)
	signal.Ignore(syscall.SIGTSTP)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	for {
		fmt.Println("hi from parent")
		time.Sleep(time.Second * 7)
	}
}
---- Additionally, when I invoke kill -SIGSTOP 1870508 (move process to T state) and then invoke kill -SIGINT 1870508 it doesn't terminate process... Why?
Asked by Yakog (517 rep)
Jan 13, 2025, 09:48 PM
Last activity: Jan 14, 2025, 10:21 AM