Please explain the ps -aef response on RHEL - host

What does pts/2 indicate in the below output. Why there is no such for other dd processes?
$ ps -aef |grep dd
root 6553672 15073352 3 02:32:19 - 0:01 dd of=/dev/lv01 bs=1024k
padmin 9437410 16515110 1 02:43:32 **pts/2** 0:00 grep dd
root 13828156 11010220 0 02:32:33 - 0:00 dd of=/dev/lv02 bs=1024k
root 14155860 13828156 2 02:32:33 - 0:01 dd of=/dev/lv02 bs=1024k
root 15073352 13762812 0 02:32:19 - 0:00 dd of=/dev/lv01 bs=1024k
root 15532200 15925276 2 02:40:47 **pts/1** 0:03 dd of=/home/padmin/sample-dd-op bs=1024k

pts/X in the TTY column means that the process is connected to a pseudo terminal slave.
An empty value means:
The terminal session has ended
The command was fired by a daemon
This nice Answer shows the difference between PTS and TTY.

Related

why open file descriptors are not getting reused instead they are increasing in number value

I have a simple C HTTP server. I close file descriptors for disk files and new connection fds returned by accept(...), but I noticed that I am getting new file descriptor numbers that are bigger than the previous numbers: for example file descriptor from accept return starts with 4, then 5, then 4 again and so on until file descriptor reaches max open file descriptor on a system.
I have set the value to 10,000 on my system but I am not sure why exactly file descriptor number jumps to max value. And I am kind of sure than my program is closing the file descriptors.
So I would like to know if there are not thousands of connections then how come file descriptor new number are increasing periodically: in around 24 hours I get message accept: too many open files. What is this message?
Also, does ulimit -n number value get reset automatically without system reboot?
as mentioned in the answer. The output of _2$ ps aux | grep lh is
dr-x------ 2 fawad fawad 0 Oct 11 11:15 .
dr-xr-xr-x 9 fawad fawad 0 Oct 11 11:15 ..
lrwx------ 1 fawad fawad 64 Oct 11 11:15 0 -> /dev/pts/3
lrwx------ 1 fawad fawad 64 Oct 11 11:15 1 -> /dev/pts/3
lrwx------ 1 fawad fawad 64 Oct 11 11:15 2 -> /dev/pts/3
lrwx------ 1 fawad fawad 64 Oct 11 11:25 255 -> /dev/pts/3
and the output of ls -la /proc/$$/fd is
root 49855 0.5 5.4 4930756 322328 ? Sl Oct09 15:58 /usr/share/atom/atom --executed-from=/home/fawad/Desktop/C++-work/lhparse --pid=49844 --no-sandbox
root 80901 0.0 0.0 25360 5952 pts/4 S+ 09:32 0:00 sudo ./lh
root 80902 0.0 0.0 1100852 2812 pts/4 S+ 09:32 0:00 ./lh
fawad 83419 0.0 0.0 19976 916 pts/3 S+ 11:27 0:00 grep --color=auto lh
I like to know what is pts/4 etc. column. is this the file descriptor number.
It's likely that the socket that is represented by the file descriptor is in close_wait or time_wait state. Which means the TCP stack holds the fd open for a bit longer. So you won't be able to reuse it immediately in this instance.
Once the socket is fully finished with and closed, the file descriptor number will then available for reuse inside your program.
See: https://en.m.wikipedia.org/wiki/Transmission_Control_Protocol
Protocol Operation and specifically Wait States.
To see what files are still open you can run
ls -la /proc/$$/fd
The output of this will also be of help.
ss -tan | head -5
LISTEN 0 511 *:80 *:*
SYN-RECV 0 0 192.0.2.145:80 203.0.113.5:35449
SYN-RECV 0 0 192.0.2.145:80 203.0.113.27:53599
ESTAB 0 0 192.0.2.145:80 203.0.113.27:33605
TIME-WAIT 0 0 192.0.2.145:80 203.0.113.47:50685

How can i create 5 Processes using fork()?

I want to create 5 processes just like the picture shown i have tried a lil bit by printing out their pid's but its hard for me to visualize the fork() creating them and get exactly what I want [The image shows 5 processes connected by pipes]
P
/ \
M M
| |
C C
When you use fork() the kernel will create one new process and will return to the child (the new process) 0 and the PID to the parent. So, knowing this this is the following code to create the tree
if ((pid = fork()) == 0) {
//I am process M1
if (pid = form()) == 0) {
//I am process C1
}
} else {
// I am still in P, so go on the next branch
if ((pid = fork()) == 0) {
//I am process M2
if (pid = form()) == 0) {
//I am process C2
}
}
}
Use ps --forest to visualize the process tree as in following example
~# ps --forest
PID TTY TIME CMD
1295 pts/0 00:00:00 sudo
1296 pts/0 00:00:00 \_ su
1297 pts/0 00:00:01 \_ bash
3541 pts/0 00:00:00 \_ ps
So you will see something like:
~# ps --forest
PID TTY TIME CMD
1295 pts/0 00:00:00 a.out
1296 pts/0 00:00:00 \_ a.out
1297 pts/0 00:00:00 \_ a.out
1298 pts/0 00:00:00 \_ a.out
1299 pts/0 00:00:00 \_ a.out
Which will tell you if you have successfully made the tree.

Problem running ps to find PID with multiple users

When I run the following code and then run ps to see the processes running, I only get 4 ./a.out running processes even though there are 5 forks. Why is that? How am I able to see the other fork? Also, if multiple people are using my computer, running the same process a.out, how can I terminate only my processes, using only linux commands? Please help.
PID TTY TIME CMD
32941 ttys000 0:00.10 -bash
34098 ttys000 0:00.08 less
33651 ttys000 0:00.00 ./a.out
33652 ttys000 0:00.00 ./a.out
33654 ttys000 0:00.00 ./a.out
33655 ttys000 0:00.00 ./a.out
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#define N 5 /* How many children to make. */
#define D 1200 /* Sleep 1200 seconds = 20 minutes */
int main(void)
{
int i;
pid_t p;
for (i = 0; i < N; i++) {
p = fork();
if (p == 0) {
close(0);
close(1);
close(2);
if (i == 2) {
setsid();
}
sleep(D);
return 0;
}
}
return 0;
}
All five processes are running, but you're using the ps command that only shows processes associated with your session, but the setsid() called for i=2 sets a different session, so the default ps options won't show you.
$ ps
PID TTY TIME CMD
3048 pts/0 00:00:00 bash
8288 pts/0 00:00:00 a.out
8289 pts/0 00:00:00 a.out
8291 pts/0 00:00:00 a.out
8292 pts/0 00:00:00 a.out
8301 pts/0 00:00:00 ps
$ ps -fe | grep a.out
steve 8288 1 0 13:39 pts/0 00:00:00 ./a.out
steve 8289 1 0 13:39 pts/0 00:00:00 ./a.out
steve 8290 1 0 13:39 ? 00:00:00 ./a.out <-- missing one
steve 8291 1 0 13:39 pts/0 00:00:00 ./a.out
steve 8292 1 0 13:39 pts/0 00:00:00 ./a.out
steve 8303 3048 0 13:40 pts/0 00:00:00 grep --color=auto a.out
$
By default, ps only displays processes with the same session id as itself and associated with a terminal. When you changed the session id of one of the processes, you disqualified it from being listed. ps x will include all of your processes.
By default, ps only lists the processes belong to you. You can be sure of this by using ps ux to include the owners of the processes in the output.
You can use the kill utility to kill these processes. Unless you are root, you can't kill other processes owned by others even if you tried.

How assign a new terminal window to each child process

I want to fork multiple processes and assign each child process it's own terminal window so that IPC can be demonstrated easily.
Forking goes on fine, and if I run the child processes on the same terminal it runs fine.
However to make each child process have its own terminal window, I do
execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);
The program runs in a new window, but its PID is different from that shown by the parent which forks the process. What am I doing wrong?
Thanks
edit1 - this is my main function (the parent process). I fork 4 child processes. I want each child process to have its own terminal window. However the child process just exits, and a new process with a different PID continues to run in the new terminal.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
pid_t pid[4];
int i = 0;
int status;
//Fork four new processes
for(i=0; i<4; i++)
{
pid[i] = fork();
if(pid[i] == 0 && i == 0)
{
execl("/usr/bin/xterm", "xterm", "./child1", NULL);
exit(1);
}
else if(pid[i] == 0 && i == 1)
{
execl("/usr/bin/xterm", "xterm", "./child2", NULL);
exit(1);
}
else if(pid[i] == 0 && i == 2)
{
execl("/usr/bin/xterm", "xterm", "./child3", NULL);
exit(1);
}
else if(pid[i] == 0 && i == 3)
{
execl("/usr/bin/xterm", "xterm", "./child4", NULL);
exit(1);
}
else
{
//Parent process
printf("The main function has forked a process with pid: %d\n", pid[i]);
}
}
for(i=0;i<4;i++)
{
status = waitpid(pid[i], NULL, 0);
if(status == pid[i])
printf("%d: Process Terminated Successfully\n", pid[i]);
else
{
perror("waitpid");
exit(1);
}
}
return 1;
}
edit2 - added ps -u output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
dell-pc 3024 0.1 0.0 26872 5480 pts/0 Ss 16:54 0:00 bash
dell-pc 3038 0.0 0.0 4200 632 pts/0 S+ 16:54 0:00 ./main
dell-pc 3039 22.5 0.1 109240 11116 pts/0 S+ 16:54 0:01 xterm ./child1
dell-pc 3040 26.1 0.1 109240 11268 pts/0 R+ 16:54 0:02 xterm ./child2
dell-pc 3041 28.7 0.1 109240 11180 pts/0 S+ 16:54 0:02 xterm ./child3
dell-pc 3042 27.0 0.1 109240 11288 pts/0 S+ 16:54 0:02 xterm ./child4
dell-pc 3044 4.1 0.0 4200 648 pts/24 Ss+ 16:55 0:00 child3
dell-pc 3046 3.7 0.0 4200 680 pts/26 Ss+ 16:55 0:00 child4
dell-pc 3048 3.8 0.0 4200 792 pts/25 Ss+ 16:55 0:00 child2
dell-pc 3050 3.3 0.0 4200 660 pts/14 Ss+ 16:55 0:00 child1
dell-pc 3060 2.0 0.0 26816 5412 pts/27 Ss 16:55 0:00 bash
dell-pc 3072 0.0 0.0 22648 2688 pts/27 R+ 16:55 0:00 ps -u
edit3: added output of main:
The main function has forked a process with pid: 3491
The main function has forked a process with pid: 3492
The main function has forked a process with pid: 3493
The main function has forked a process with pid: 3494
3491: Process Terminated Successfully
3492: Process Terminated Successfully
3493: Process Terminated Successfully
3494: Process Terminated Successfully
I did a program like yours (naming it stackoverflow), executing vi in an xterm, and while it is running I open a third xterm to run ps -u. Output is:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
osboxes 1713 0.0 0.2 6588 4756 pts/0 Ss 18:56 0:00 bash
osboxes 1780 0.0 0.2 6508 4484 pts/1 Ss 19:12 0:00 bash
osboxes 1836 88.4 0.0 2020 532 pts/0 R+ 19:21 0:29 ./stackoverflow
osboxes 1837 0.1 0.4 12844 8952 pts/0 S+ 19:21 0:00 /usr/bin/xterm -e vi stackoverflow.txt
osboxes 1839 0.0 0.1 6072 3536 pts/2 Ss+ 19:21 0:00 vi stackoverflow.txt
osboxes 1840 0.0 0.1 4772 2452 pts/1 R+ 19:22 0:00 ps -u
Output of program is:
PID=1836
child PID=1837
So the child is still running xtermcommand. It created another child running vi (pid 1839).
IPC Demo and sample using terminal windows, under bash
Because it's easy under bash:
This will require simple terminal tools, like xterm. This was successfully tested with lxterm, mate-terminal, konsole and gnome-terminal. Of course, tmux and screen must be able too...
Ok, let's go. We assume you're already in some terminal window, we will name this initial console.
1. First opening a display window:
So, from the initial console, open log window:
exec 5> >(xterm -T 'Log window...' -e sh -c "cat /proc/$$/fd/5")
or
exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")
exec 5> >(konsole --nofork -e sh -c "cat /proc/$$/fd/5")
exec 5> >(lxterm -T "Log window..." -e sh -c "cat /proc/$$/fd/5")
exec 5> >(mate-terminal -t 'Log window...' -x sh -c "cat /proc/$$/fd/5")
exec 5> >(gnome-terminal --window -x sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")
Variant usefull for debugging
exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f -")
Will print date and time on each line output.
exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f - ; read foo")
Same, but will keep window open after closing from parent, waiting for terminal input (Return) before closing (or close by window manager).
2. Testing, then using this:
Always in initial console, hit:
echo >&5 This is a test string.
This must prompt in Log window.
Ok, now:
xterm -T 'Input window' -e bash --rcfile <(echo "exec 1>/proc/$$/fd/5") &
Note: There, double-quotes will ensure $$ will expand from initial window's shell level.
So now, you could enter command in Input window and read results on Log window.
3. Closing window
Window will close when file descriptor is closed:
exec 5>&-
Full script using 3 window
You may found full script there:
ipc_win-demo.sh.txt
ipc_win-demo.sh
For gnome terminal I used:
execl("/usr/bin/gnome-terminal", "gnome-terminal", "-q", "-e", "./my_binary", (char*)0);

fork() and kill in linux

In my project, I need a sub-task to play in parallel with a parent task. I use fork() to create a parallel process which is aplay xyz.wav. Now when I want to kill the child process from the parent process e.g system("kill -9 aplay ") the aplay is killed, but I see two instances of the parent task. I think one of them is a copy made by the call to fork() and the other one is the original. And with each fork() call, the number of copies increases. I am conscious about memory overflow. I just want to keep the original process. I have tried to kill that parent copy but failed!copies of the parent process appear as 'defunct'.
the 'defucnt' process continue to increase as i call parallel process, whether i kill aplay or not. I also tried to kill defunt by its PID, it also didn't work.
static int
test(Core *pc, char *args)
{
pid1=fork();
if (pid1 ==0)
{
system ("ps " );
system("aplay /opt/Line_Tone_14s.wav");
_exit(0);
}
else if(pid1<0)
{
out("fork() ERROR (-1) returned\n");
}
else if(pid1>0)
{
out("I AM IN PARENT PROCESS() NOW\n");
}
return 1;
}
static int
test1(Core *pc, char *args)
{
system ("ps " );
system ("killall -9 aplay ");
return 1;
}
Initially
> PID TTY TIME CMD
1580 pts/0 00:00:00 sudo
1581 pts/0 00:00:00 su
1589 pts/0 00:00:00 bash
5732 pts/0 00:00:00 parent
5738 pts/0 00:00:00 sh
5739 pts/0 00:00:00 ps
>test
> PID TTY TIME CMD
1580 pts/0 00:00:00 sudo
1581 pts/0 00:00:00 su
1589 pts/0 00:00:00 bash
5732 pts/0 00:00:00 parent
5737 pts/0 00:00:00 parent
5740 pts/0 00:00:00 sh
5741 pts/0 00:00:00 aplay
5743 pts/0 00:00:00 sh
5744 pts/0 00:00:00 ps
>test1
>killed
after kill
>PID TTY TIME CMD
1580 pts/0 00:00:00 sudo
1581 pts/0 00:00:00 su
1589 pts/0 00:00:00 bash
5732 pts/0 00:00:00 parent
5737 pts/0 00:00:00 parent <defunct>
5753 pts/0 00:00:00 sh
5754 pts/0 00:00:00 ps
>test
> PID TTY TIME CMD
1580 pts/0 00:00:00 sudo
1581 pts/0 00:00:00 su
1589 pts/0 00:00:00 bash
5732 pts/0 00:00:00 parent
5737 pts/0 00:00:00 parent <defunct>
5759 pts/0 00:00:00 parent
5762 pts/0 00:00:00 sh
5763 pts/0 00:00:00 aplay
5765 pts/0 00:00:00 sh
5766 pts/0 00:00:00 ps
>test1
>killed
after kill
>PID TTY TIME CMD
1580 pts/0 00:00:00 sudo
1581 pts/0 00:00:00 su
1589 pts/0 00:00:00 bash
5732 pts/0 00:00:00 parent
5737 pts/0 00:00:00 parent <defunct>
5759 pts/0 00:00:00 parent <defunct>
5773 pts/0 00:00:00 sh
5774 pts/0 00:00:00 ps
i also tried with this in test() command
else if(pid1>0)
{
out("I AM IN PARENT PROCESS() NOW\n");
wait(&status);
}
by doing this only one parent process remain after aplay finishes to play sound, no matter how many times i call the "test" command. but the issue with this is that, I can not type any other command during sound play, until it finishes. so could not kill it in between playing the sound.
I want to play sound in parallel, and want to kill any time i want.
Don't kill it that way! You have the child PID in pid1, just use the kill() function to kill it.
Spawning an separate process to run killall is unnecessary, expensive and (as you've found out), not that reliable. What if there are five copies of that executable running?
You can use something like:
#include <sys/types.h>
#include <signal.h>
:
int rc = kill (pid1, 9); // or SIGKILL for portability, rather than 9.
// Check rc and errno.
in your parent.
I would also seriously look into removing the system calls in the child process as well since they start up separate processes. You can do better by using the exec family of calls the replace the program in the child's process space.

Resources