Get information on PID - c

I'm trying to get the information on a PID via c or terminal (ideally I would like to get it both ways, multiple methods)
I have a PID and would like to figure out the time it was claimed. By claimed i mean when a program started using it. Or if a PID was reused, when the latest program that is using it, started to use it.
In Linux what I do is lstat "/proc/PID_HERE/exe" or lstat "/proc/PID_HERE/cmdline" but I cant figure out how to do this on Mac OS.
Note: I changed from stat to lstat because a single exe is being used with command line arguments to open multiple instances. So each instance gets a new pid, so I want info on that specific instance, thus on Linux I have to use lstat. So any lstat equivalent to get pid info on mac os?

I think you mean this:
ps -p <PID> -o start=
10:22am
where you substitute in your PID. The start= selects the start time and also suppresses the header line. If you want the header, use
ps -p <PID> -o start
STARTED
10:22am
Alternatively, you can get the start time formated more fully like this:
ps -p <PID> -o lstart=
Fri 26 Sep 10:22:50 2014
By the way, if you want a list of the keywords (like start and lstart above) you can either wade through the manage, or more simply, just give an invalid keyword and it will tell you all the ones it likes :-)
ps -o %rubbish
ps: %rubbish: keyword not found
ps: no valid keywords; valid keywords:
%cpu %mem acflag acflg args blocked caught comm command cpu cputime etime f flags gid group ignored
inblk inblock jobc ktrace ktracep lim login logname lstart majflt minflt msgrcv msgsnd ni nice nivcsw
nsignals nsigs nswap nvcsw nwchan oublk oublock p_ru paddr pagein pcpu pending pgid pid pmem ppid pri
pstime putime re rgid rgroup rss ruid ruser sess sig sigmask sl start stat state stime svgid svuid
tdev time tpgid tsess tsiz tt tty ucomm uid upr user usrpri utime vsize vsz wchan wq wqb wql wqr xstat

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);

Linux Command Outputs Terminated Processes

I'm working in C and using the following code to execute the ps linux command:
char *const parmList[] = {"ps","-o","pid","-g",processGroupID,NULL};
execvp(parmList[0], parmList);
The problem is that it prints all the processes from the group including ones that have been terminated. I need to make sure that the group processes that have NOT been terminated are the only ones shown. Is there a way to do this?
ps command display's the list of active processes of that current tty terminal.
ps - axrgo pid or ps -axro pid -g
ps has an simple process selection option.
-a -------> Select all processes except both session leaders and processes not associated with a terminal. i.e includes all active terminals
-e -------> Includes all processes.
-g -------> Select by session OR by effective group name.
-r -------> Restrict the selection to only running processes.
-x -------> option causes ps to list all processes owned by you (same EUID as ps), or to list all processes when used together with the a option.
Add the a x r options to get only running processes.

Can I interact with an open vt from a c program?

Assume I have a state machine started as root to run one and only one program in a given reserved vt. The first call I use something like:
execl("/usr/bin/openvt", "/usr/bin/openvt", "-c 12", "-f", "-- su auser /home/auser/sbin/ascript.sh", (char *) 0);
Is the only way to find the PID's of all of the children (The shell script, the calls, etc) to search ps aux for the PID's that are generated on that vt (tty12) and kill them, as fork only will hold the PID of the openvt command which pretty much dies after the new vt is open?
Or is there a slick way to send a SIGINT to a known vt (i.e., /dev/vcs12 dev/tty12)?
The -t tty option to ps may be what you are looking for...
kill -INT `ps -t vcs12 -o pid=`
or, in a sh/bash-specific way:
kill -INT $(ps -t vcs12 -o pid=)

Implementing my own ps command

I'm trying to implement my own ps command, called psmod.
I can use linux system call and all utilities of the /proc directory.
I discovered that all directory in /proc directory with a number as their name are the processes in the system. My question is: how can I select only those processes which are active when psmod is called?
I know that in /proc/<pid>/stat there's a letter representing the current status of the process; anyway, for every process in /proc, this letter is S, that is sleeping.
I also tried to send a signal 0 to every process, from 0 to the maximumnumberofprocesses (in my case, 32768), but in this way it discovers far more processes than the ones present in /proc.
So, my question is, how does ps work? The source is a little too complicated for me, so if someone can explain me, I would be grateful.
how does ps work?
The way of learning standard utils - is to check their source code. There are several implementations of ps: procps and busybox; and busybox is smaller and it will be easier to begin with it. There is sources for ps from busybox: http://code.metager.de/source/xref/busybox/procps/. Main loop from ps.c:
632 p = NULL;
633 while ((p = procps_scan(p, need_flags)) != NULL) {
634 format_process(p);
635 }
Implementation of procps_scan is in procps.c (ignore code from inside ENABLE_FEATURE_SHOW_THREADS ifdefs for first time). First call to it will open /proc dir using alloc_procps_scan():
290 sp = alloc_procps_scan();
100 sp->dir = xopendir("/proc");
Then procps_scan will read next entry from /proc directory:
292 for (;;) {
310 entry = readdir(sp->dir);
parse the pid from subdirectory name:
316 pid = bb_strtou(entry->d_name, NULL, 10);
and read /prod/pid/stat:
366 /* These are all retrieved from proc/NN/stat in one go: */
379 /* see proc(5) for some details on this */
380 strcpy(filename_tail, "stat");
381 n = read_to_buf(filename, buf);
Actual unconditional printing is in format_process, ps.c.
So, busybox's simple ps will read data for all processes, and will print all processes (or all processes and all threads if there will be -T option).
how can I select only those processes which are active when psmod is called?
What is "active"? If you want find all processes that exists, do readdir of /proc. If you want to find only non-sleeping, do full read of /proc, check states of every process and print only non-sleeping. The /proc fs is virtual and is it rather fast.
PS: for example, normal ps program prints only processes from current terminal, usually two:
$ ps
PID TTY TIME CMD
7925 pts/13 00:00:00 bash
7940 pts/13 00:00:00 ps
but we can strace it with strace -ttt -o ps.log ps and I see that ps does read every process directory, files stat and status. And the time needed for this (option -tt of strace gives us timestamps of every syscall): XX.719011 - XX.870349 or just 120 ms under strace (which slows all syscalls). It takes only 20 ms in real life according to time ps (I have 250 processes in total):
$ time ps
PID TTY TIME CMD
7925 pts/13 00:00:00 bash
7971 pts/13 00:00:00 ps
real 0m0.021s
user 0m0.006s
sys 0m0.014s
"My question is: how can I select only those processes which are active when psmod is called?"
I hope this command will help you:
top -n 1 | awk "NR > 7" | awk {'print $1,$8,$12'} | grep R
I am on ubuntu 12.

How do get the process name & process id pid of newly created child process using fork?

I am using fork to create the child process. Now I want to know the name and process id of the child process using putty. Which command I need to use to get this information. I am trying with ps and pstree. how can give the name of the child process while creating new child process? Is it possible to get this information using any linux/unix command?
I want to know how much time child is active and when it is terminated. mean timing information of child process.
root#mx6q:~# ps aux|grep "childprogram"
ps: invalid option -- 'a'
BusyBox v1.20.2 (2014-03-13 11:47:37 CET) multi-call binary.
Usage: ps
Show list of processes
w Wide output
l Long output
T Show threads
root#mx6q:~#
root#mx6q:~# ps | grep "childprogram"
1407 root 1908 S grep childprogram
root#mx6q:~# ps | grep "childprogram"
1409 root 1908 S grep childprogram
root#mx6q:~# ps | grep "childprogram"
1411 root 1908 S grep childprogram
For Parent:
root#mx6q:~# readlink /proc/670/exe
.asoundrc .gvfs/
.bashrc adit-30-09-2014.vnclicense
.gstreamer-0.10/ enable_usb_dr_host_mode.sh
root#mx6q:~# readlink /proc/670/exe
but I am not able to find child pid inside /proc/? What does it mean?
You tagged this as C and mentioned that you are the actor forking the new process so you have all this information available to you in the parent process that forks the child but you need to alter your code to capture it.
You have the child's pid because it is returned in the parent by fork.
You (probably) have the child's name because under most circumstances you are the one who wrote the exec call. If not, with the child's pid you can readlink /proc/<pid>/exe.
If you need to know the child's stats while it is running you can call getrusage with the RUSAGE_CHILDREN option.
If you just want the child's stat's after it is completed you can wait on it with wait4
Try this:
$ ps xf
And analyze the output and make some filters with grep sed and/or awk.
I am not very much familiar with BusyBox as I know it is a tiny distro with limited functions.

Resources