5

Given a process' pid, how can I determine if the process is paused (with SIGSTOP) or running?

I'm using OS X, so I don't have a /proc directory.

Tyilo
  • 28,998
  • 40
  • 113
  • 198

3 Answers3

2

It's not a great answer, but it IS an answer.. you can run ps aux (from within your program) and see if the STAT column is T (stopped). Just checked that on mountain lion.

Not sure how it figures it out.

I think I'm getting closer with the kvm_* functions:

Get other process' argv in OS X using C

also

kvm_getargv()

http://www.daemon-systems.org/man/kvm_getproc2.3.html and the source for PS: http://bxr.su/o/bin/ps/ps.c

Community
  • 1
  • 1
xaxxon
  • 19,189
  • 5
  • 50
  • 80
2

This is how you do it:

#include <stdio.h>
#include <sys/sysctl.h>
#include <stdlib.h>
#include <string.h>

#define IS_RUNNING(proc) ((proc->kp_proc.p_stat & SRUN) != 0)

#define ERROR_CHECK(fun) \
    do { \
        if(fun) { \
            goto ERROR; \
        }\
    } while(0)

struct kinfo_proc *proc_info_for_pid(pid_t pid) {
    struct kinfo_proc *list = NULL;

    int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    size_t size = 0;

    ERROR_CHECK(sysctl(mib, sizeof(mib) / sizeof(*mib), NULL, &size, NULL, 0));

    list = malloc(size);
    ERROR_CHECK(sysctl(mib, sizeof(mib) / sizeof(*mib), list, &size, NULL, 0));

    return list;

ERROR:
    if(list) {
        free(list);
    }
    return NULL;
}

int main() {
    pid_t pid = 1000;
    struct kinfo_proc *proc_info = proc_info_for_pid(pid);
    if(proc_info) {
        printf("Is running: %d\n", IS_RUNNING(proc_info));
    } else {
        printf("Could not stat process!");
        return 1;
    }
    return 0;
}
Tyilo
  • 28,998
  • 40
  • 113
  • 198
0

In man ps you can read about T state of the process:

T Marks a stopped process.

To determine if the process is stopped, running ps j will show you T flag in stat column.

In Bash to show all current stopped processes, run: jobs -s (see help jobs). To kill them run: kill $(jobs -sp).

If these processes aren't attached to the current shell, to show all stopped processes, this command may help:

ps wuax | awk '$8 ~ "T"'

Here is command to resume all stopped processes:

kill -CONT $(ps wuax | awk 'NR>1 && $8 ~ "T" {print $2}')

To kill these processes instead, replace -CONT with -9.

If you have paused processes, they won't show as stopped (with T), so to resume them, use the following command instead:

pkill -CONT -u $UID

or for a specific process (such as Chrome), try:

kill -CONT $(pgrep Chrome)
kenorb
  • 155,785
  • 88
  • 678
  • 743