2

My C program running under Linux wants to find out, by name, if another program is running. How to do it?

Mat
  • 202,337
  • 40
  • 393
  • 406
Pete Wilson
  • 8,610
  • 6
  • 39
  • 51
  • 1
    @Mat -- "by name" means I want to issue a function call with a program name as a C-string as an argument and get a boolean return: true for yes, this named program is running; or false for no,this named program is not running. I haven't tried anything, but only googled and found nothing. I would try system( ps ) or similar but I am hoping for something much simpler and more straightforward. – Pete Wilson Oct 01 '11 at 09:05

4 Answers4

6

There are two ways basically:

  • Use popen("pgrep yourproc", "r"); and then fgets from it
  • Use opendir and readdir to parse /proc - this is basically what ps(1) does

Not the cleanest but I would go with the first of these.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 1
    I'd go for the second just because you can find lots of interesting stuff in `/proc/$pid` - real instructive. – Mat Oct 01 '11 at 09:10
  • 1
    @Mat Sure, it's way more interesting and it's technically **the right way** to do it (not spawning two processes, no using the shell, etc). But you have to be pragmatic: it takes loads more time to write and I wouldn't say it's exactly easy. – cnicutar Oct 01 '11 at 09:12
  • 1
    You're certainly right about that. Just the directory traversal, when you can expect directories to disappear from under you is a _fun_ exercise in error handling. – Mat Oct 01 '11 at 09:14
  • Thanks, guys. Upvoted everything. I'll use popen("pgrep the_proc_name", "r" ) because it returns an exit status for yes or no, which is just what I want for this simple-minded temp solution. Didn't know abt pgrep. – Pete Wilson Oct 01 '11 at 09:22
  • 1
    Although you seem to have decided to go for the quick&dirty trail, I'd like to point you to this: http://procps.sourceforge.net/ ... just in case you change your mind ... ;-) – alk Oct 01 '11 at 10:45
3

Travesing /proc really isn't much harder than popen(). Essentially you do 3 things

  • Open all number formatted /proc entries.
  • Get the command invocation through /proc/<PID>/command/
  • Perform a regex match for the name of the processs you want.

I've omitted some error handling for clarity, but It should do something like what you want.

int 
main()
{
    regex_t number;
    regex_t name;
    regcomp(&number, "^[0-9]+$", 0);
    regcomp(&name, "<process name>", 0);
    chdir("/proc");
    DIR* proc = opendir("/proc");
    struct dirent *dp;
    while(dp = readdir(proc)){
         if(regexec(&number, dp->d_name, 0, 0, 0)==0){
              chdir(dp->d_name);
              char buf[4096];
              int fd = open("cmdline", O_RDONLY);
              buf[read(fd, buf, (sizeof buf)-1)] = '\0';
              if(regexec(&name, buf, 0, 0, 0)==0)
                    printf("process found: %s\n", buf);
              close(fd);
              chdir("..");
         }
    }
    closedir(proc);
    return 0;
}
Dave
  • 10,964
  • 3
  • 32
  • 54
2

In unix, programs do not run. Processes run. A process can be viewed as an instance of a program. A process can operate under another name or change its name, or have no name at all. Also, at the time of running, the program can even have ceased to exits (on disk) and only exist in core. Take for instance the following program: (is /dev/null actually running? I don't think so ...)

#include <unistd.h>
#include <string.h>

int main(int arc, char **argv)
{

if (strcmp(argv[0], "/dev/null") ) {
    execl( argv[0], "/dev/null", NULL );
    }

sleep (30);
return 0;
}
wildplasser
  • 43,142
  • 8
  • 66
  • 109
0

If you want to look at the 'right' way to do this, check out the following:

Linux API to list running processes?

Community
  • 1
  • 1
David C. Bishop
  • 6,437
  • 3
  • 28
  • 22