By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,877 Members | 1,100 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,877 IT Pros & Developers. It's quick & easy.

How to check for already running program?

P: n/a
Hi all,
I'm new to C.

I have successfully written a small C program that acts as a "wrapper"
around cgi scripts. These scripts perform admin tasks such as backing up
etc. Obviously, The need for the "wrapper" was to get the scripts to run
with "root" privileges. So far so good. I simply create a "URL shortcut"
that some staff can double-click on to initiate the process.

However, because I am creating these automated tasks for management staff
of a company, I want to make sure that they don't go laucnching these tasks
twice or similar (2 or more similtaneous backup processes to the same drive
at the same time is not nice).

I thought the bast way to address this was just to grab a "process listing"
and use the available "regcomp and regexec" functions to check that there
is not already and instance of the designated script running. If so, baulk
and exit with a message.

The thing I don't understand; is that when testing this, any attempts to
run additional instances of the script using the c program don't work,
because the "new instance" will wait until the old process finishes, and
then start (which is not what I want).

BTW: I call it like this
http://some.internal.address/cgi-bin...?fw_backup.cgi

Could someone please point me in the right direction?

TIA
/* This program was created to get around the problem */
/* of having to do tasks that require root privileges */
/* but aren't possible when run as a simple cgi script. */
/* Set this binary to run suid and make sure it's owned */
/* by root, and you're good to go. */
/* Nick Sinclair 2005 GPL it's all yours. */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <regex.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[], int ac, char *av[]){

/* Declare some variables */

FILE *cgi_file;
FILE *process_listing;

char line[130];
int counter = 0;

pid_t pid;

char *pattern = argv[1];

int regex_result;
regex_t re;

/* Let's do some sanity checks on the cgi script name */

/* Argument supplied at all? */

if (argc==1)
{ printf("\nNo CGI script name supplied - Freaking out and
exiting.\n\n");
exit(172);
}

/* Too many arguments? */

if (argc>2)
{ printf("\nToo many arguments supplied - Freaking out and
exiting.\n\n");
exit(172);
}

/* Does the file exist at all? */

cgi_file = fopen(argv[1], "r");
if (cgi_file==NULL)
{ printf("\nSupplied file cannot be read from or doesn't exist\n");
printf(" - Freaking out and exiting -\n\n");
exit(127);
}

/* Is the script already running - doh! */

regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB);
process_listing=popen("ps ax", "r");

while ( fgets( line, sizeof line, process_listing))
{
regex_result=regexec(&re, line, (size_t) 0, NULL, 0);
/* printf("Result = %d\n", regex_result); */

if (regex_result==0)
{
/* printf("%s", line); */
counter++;
}

}

pclose(process_listing);
regfree(&re);

if (counter>1)
{
printf("Script already running! - Freaking out and exiting.\n\n");
exit(172);
}

/* Set UID to 0 (root) */

setuid(0);

/* Now run the actual ".cgi" file */

/* pid=getpid(); */
execl("/usr/bin/bash", "bash", argv[1], (char *)0);

}

Nov 15 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
One quite simple way would be to open a socket at a specified port when
the application starts. When the second instance starts and tries to
open the same port it will fail. One has to take care however that no
other application open the same port while the application is not
running.

A better way might be to create a appname.pid-file in /var/run/ when
starting the application and check it one exists when starting. Problem
with this is that if the application crashes before removing the the
file can prevent it from starting again. To prevent this check the PID
in the file and see if any running process has this PID.

--
Erik Wikström

Nov 15 '05 #2

P: n/a
"Nick Sinclair" <nu*********@NOFRILLS.ssl-mail.com> wrote in message
news:jo********************************@4ax.com...
[snip]
However, because I am creating these automated tasks for management staff
of a company, I want to make sure that they don't go laucnching these
tasks twice or similar (2 or more similtaneous backup processes to the
same drive at the same time is not nice).


I don't know of a reliable method within the scope of ANSI C, the topic of
this newsgroup. On Unix systems, file locking can be used for mutual
exclusion - you should ask about this in a platform-specific newsgroup,
perhaps news:comp.unix.programmer.

Also, you need to be particularly wary of security issues when you expose a
means to invoke processes as root. Again, off-topic for this newsgroup.

Alex
Nov 15 '05 #3

P: n/a
# "Nick Sinclair" <nu*********@NOFRILLS.ssl-mail.com> wrote in message
# news:jo********************************@4ax.com...

# > However, because I am creating these automated tasks for management staff
# > of a company, I want to make sure that they don't go laucnching these
# > tasks twice or similar (2 or more similtaneous backup processes to the
# > same drive at the same time is not nice).

Decide on some specific file path in the system.
int fd = open(path,O_WRONLY|O_CREAT,0600);
int rc = flock(fd,LOCK_EX|LOCK_NB);

If rc==-1, another process is already in the critical section.

If rc==0, this process has acquired the lock. If the process exits
for any reason, the lock is released by the kernel. The process can
also exit the critical section with
flock(fd,LOCK_UN);

--
SM Ryan http://www.rawbw.com/~wyrmwif/
I have no respect for people with no shopping agenda.
Nov 15 '05 #4

P: n/a
Let's see what SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org>
has up their dress.
# "Nick Sinclair" <nu*********@NOFRILLS.ssl-mail.com> wrote in message
# news:jo********************************@4ax.com...

# > However, because I am creating these automated tasks for management staff
# > of a company, I want to make sure that they don't go laucnching these
# > tasks twice or similar (2 or more similtaneous backup processes to the
# > same drive at the same time is not nice).

Decide on some specific file path in the system.
int fd = open(path,O_WRONLY|O_CREAT,0600);
int rc = flock(fd,LOCK_EX|LOCK_NB);

If rc==-1, another process is already in the critical section.

If rc==0, this process has acquired the lock. If the process exits
for any reason, the lock is released by the kernel. The process can
also exit the critical section with
flock(fd,LOCK_UN);


Sweet.
Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.