How can I get the sender pid while receving the SIGSTOP? - c

As we know, SIGSTOP can't be handled, but my app is always stopped by it.
I receive this report(about my app stopped by SIGSTOP) by using WIFSTOPED/WSTOPSIG functions in my monitor process.
So, how can I do this job?

using audit !!
centos6:
adding line to /etc/audit/audit.rules(19 is the signal no. i need):
-a entry,always -F arch=b64 -S kill -k teste_kill -F a1=19
then
service auditd restart
finally, show log by this:
ausearch -k teste_kill

Related

Linux Command to Show Stopped and Running processes?

I'm presently executing the following Linux command in one of my c programs to display processes that are running. Is there anyway I can modify it to show stopped processes and running ones?
char *const parmList[] = {"ps","-o","pid,ppid,time","-g","-r",groupProcessID,NULL};
execvp("/bin/ps", parmList);
jobs -s list stopped process by SIGTSTP (20), no SIGSTOP (19). The main difference is that SIGSTOP cannot be ignored. More info with help jobs.
You can SIGTSTP a process with ^Z or from other shell with kill -TSTP PROC_PID (or with pkill, see below), and then list them with jobs.
But what about listing PIDs who had received SIGSTOP? One way to get this is
ps -A -o stat,command,pid | grep '^T '
From man ps:
-A Select all processes. Identical to -e.
T stopped by job control signal
I found very useful this two to stop/cont for a while some process (usually the browser):
kill -STOP $(pgrep procName)
kill -CONT $(pgrep procName)
Or with pkill or killall:
pkill -STOP procName
pkill -CONT procName
Credit to #pablo-bianchi, he gave me the oompff (starting point) to find SIGSTOP'd and SIGTSTP'd processes, however his answers are not completely correct.
Pablo's command should use T rather than S
$ ps -e -o stat,command,pid | grep '^T '
T /bin/rm -r 2021-07-23_22-00 1277441
T pyt 999 1290977
$ ps -e -o stat,command,pid | grep '^S ' | wc -l
153
$
From man ps:
PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT"
or "S") will display to describe the state of a process:
D uninterruptible sleep (usually IO)
I Idle kernel thread
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped by job control signal
t stopped by debugger during the tracing
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent
WRT pgrep, it is a real grep, the argument is NOT a program name; rather, it is a regular expression applied to the first item in /proc//cmdline (usually the name from the executing commandline (or execve()).
Therefore if you are trying to kill pyt, you would accidentally also kill all the python programs that are running:
$ pgrep -a pyt
7228 python3 /home/wwalker/bin/i3-alt-tab-ww --debug
1290977 pyt 999
You need to "anchor" the regular expression:
$ pgrep -a '^pyt$'
1290977 pyt 999
ps -e lists all processes.
jobs list all processes currently stopped or in background.
So, you can run jobs command using execvp:
char *arg = {"jobs", NULL};
execvp(arg[0], arg);

C: How to kill a process on another machine through SSH?

I am looking to run a program written in C on my machine and have it SSH into another machine to kill a program running on it.
Inside my program, I have attempted:
system("ssh username#machine.com && pkill sleep && exit");
which will cause my terminal to SSH into the remote machine, but it ends there. I have also tried:
execl("ssh","ssh","username#machine.com",NULL);
execl("pkill","pkill","sleep",NULL);
execl("exit","exit",NULL);
but it will not kill my dummy sleep process I have running.
I can't seem to figure out what is wrong with my process.
Your second example won't do what you want as it will execute each execl on the local machine. IE it will
Execute ssh usrname#machine.com
Execute pkill
Execute exit
But, actually, unless you are surrounding these by fork, the first execl if it succeeds in running at all will replace the current process, meaning the second and third ones never get called.
So, let's work out why the first (more hopeful) example doesn't work.
This should do the equivalent of:
/bin/sh -c 'ssh username#machine.com && pkill sleep && exit'
The && exit is superfluous. And you want the pkill to run on the remote machine. Therefore you want something that does:
/bin/sh -c 'ssh username#machine.com pkill sleep'
(note the absence of && so the pkill is run on the remote machine).
That means you want:
system("ssh username#machine.com pkill sleep");
If that doesn't work, check the command starting /bin/sh -c above works. Does ssh ask for a password, for instance? If so, it won't work. You will need to use a public key.
one can always run, over ssh, the command:
kill $(pgrep -o -f 'command optional other stuff')
Get your remote process to handle SIGTERM, where it can do its cleanup's. (including killing any processes its started)
Google 'man pgrep' to see what the -o and -f do. -f is important to correctly target the signal.
the 'pgrep' returns the pid with trailing \n but this does not need to be stripped off before passing it to 'kill'.
Yours
Allan

Application crashes only when launched from inittab on busybox

I'm writing an application for an embedded busybox system that allows TCP connections, then sends out messages to all connected clients. It works perfectly when I telnet to the box and run the application from a shell prompt, but I have problems when it is launched from the inittab. It will launch and I can connect to the application with one client. It successfully sends one message out to that client, then crashes. It will also crash if I connect a second client before any messages are sent out. Again, everything works perfectly if I launch it from a shell prompt instead.
The following errors are what comes up in the log:
<11>Jan 1 00:02:49 tmmpd.bin: ERROR: recvMessage failed, recv IO error
<11>Jan 1 00:02:49 tmmpd.bin: Some other LTK TCP error 103. Closing connection 10
<11>Jan 1 00:02:49 tmmpd.bin: ERROR: recvMessage failed, recv IO error
<11>Jan 1 00:02:49 tmmpd.bin: Some other LTK TCP error 103. Closing connection 10
Any suggestions would be greatly appreciated!
I was testing a bit in arm-qemu and busybox, and I was able to start a script as user test to run in background.
I have created a new user "test":
buildroot-dir> cat etc/passwd
test:x:1000:1000:Linux User,,,:/home/test:/bin/sh
Created a simple testscript.sh:
target_system> cat /home/test/testscript.sh
#!/bin/sh
while :
do
echo "still executing in bg"
sleep 10
done
To my /etc/init.d/rcS I added a startup command for it:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
/bin/su test -c /home/test/testscript.sh& # < Added this
Now when I start the system, the script will run in the background, and when I grep for the process it has been started as user test (default root user is just 0):
target_system> ps aux | grep testscript
496 test 0:00 sh -c home/test/testscript.sh
507 test 0:00 {testscript.sh} /bin/sh home/test/testscript.sh

Executing shell script with system() returns 256. What does that mean?

I've written a shell script to soft-restart HAProxy (reverse proxy). Executing the script from the shell works. But I want a daemon to execute the script. That doesn't work. system() returns 256. I have no clue what that might mean.
#!/bin/sh
# save previous state
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.old
mv /var/run/haproxy.pid /var/run/haproxy.pid.old
cp /tmp/haproxy.cfg.new /home/haproxy/haproxy.cfg
kill -TTOU $(cat /var/run/haproxy.pid.old)
if haproxy -p /var/run/haproxy.pid -f /home/haproxy/haproxy.cfg; then
kill -USR1 $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid.old
exit 1
else
kill -TTIN $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid
mv /var/run/haproxy.pid.old /var/run/haproxy.pid
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.err
mv /home/haproxy/haproxy.cfg.old /home/haproxy/haproxy.cfg
exit 0
fi
HAProxy is executed with user haproxy. My daemon has it's own user too. Both run with sudo.
Any hints?
According to this and that, Perl's system() returns exit values multiplied by 256. So it's actually exiting with 1. It seems this happens in C too.
Unless system returns -1 its return value is of the same format as the status value from the wait family of system calls (man 2 wait). There are macros to help you interpret this status:
man 3 wait
Lists these macros and what they tell you.
A code of 256 probably means that the system command cannot locate the binary to run it. Remember that it may not be calling bash and that it may not have paths setup. Try again with full paths to the binaries!
I have the same problem when call script that contains `kill' command in a daemon.
The daemon must have closed the stdout, stderr...
Use something like system("scrips.sh > /dev/null") should work.

system command hanged in C program, but when I run the command on bash it is successfull

I need to send the arp of a IP to get it's mac address which is configured on different machine. I am arping this ip from a C program by "system(arping -c 3 -i eth0 ) but I see that this is hanged in there.
But if I run the same command from bash "arping -c 3 -i eth0 " it get executed successfully.
I could not understand why system command hanged in this case while the command is successfully completed when run from bash.
Thanks,
Since you said it was hanging you can try:
strace -o my_prog.strace -f ./my_prog
and then kill it after it hangs. Then you can view the strace output file my_prog.strace and try to figure out what went wrong.
You may want to look at the strace man page to see other options that you might like use -- of particular use to me are ones that make it show more data in buffer (and string) input/output.
If it's not really hanging you should check the return value from your call to system( ) and then inspect errno.
edit
Something that I just thought of that could cause a hang would be if arping was actually a link to a setuid root program that did sudo on the real arping and it is waiting on a password to be typed in, but the terminal for that program isn't set correctly.
try system("arping -c 3 -I eth0 ip-addr");
something like:
main()
{
system("arping -c 3 -I eth0 192.168.10.1");
}
Are you using any child process to execute above ?
From Definition of system() :
The system() function shall ignore the SIGINT and SIGQUIT signals, and shall block the SIGCHLD signal, while waiting for the command to terminate. The system() function shall not return until the child process has terminated.
Recommendations:
1.check on the return value of system() & take appropriate decision.
Eg: If return value is zero it means command processor is not available.If a child process cannot be created, or if the termination status for the command language interpreter cannot be obtained, system() shall return -1 and set errno to indicate the error.
2.Use complete shell commands to be executed.
Eg: system("arping -c 3 -I eth0 10.203.198.10");

Resources