On Tue, 26 Apr 2005 09:21:40 -0400, Vladislav Grinchenko wrote:
>
> In short, this happens when I try to handle PID file locking to preclude
> multiple instances of the same program simultaneously running on a
> host.
>
> If there is a more preferable way of handling this task in cygwin/win32,
> I wouldn't mind implementing it.
You can use "file creation test & lock" instead of UNIX file area
locking. Attached source for "crtst-tmout" command is below.
To check if another copy is in memory you can check the /proc file
system. You can use the attached source below as an example.
Instead of /proc//stat you may use /proc//exename (this
does not exist on UNIX, and /proc//exe needs root permission).
Ehud.
- proc fs searching -
#include
#include
#include
#include
#include
#include
#include /* for kill */
char *get_pname ( pid_t pid ) ;/* find program name from pid
returns program name or ""
uses /proc//stat*/
pid_t next_pid ( int cont ) ; /* get next pid from /proc
cont should be 0 on 1st call,
!= 0 on continuation
returns: pid (>0)
0 - no more pids
<0 - error */
void kill_old ( void ) /* kill other instances */
{
pid_t my_pid , pid = 0 ; /* my pid , pid (temp) to
check */
char my_name [ 256 ] , *pname ;/* my name, temp program
name */
my_pid = getpid ( ) ; /* get my pid */
pname = get_pname ( my_pid ) ;
if ( *pname == 0 ) /* empty name - Error */
return ;
strcpy ( my_name ,pname ) ; /* save my name */
while ( ( pid = next_pid ( pid ) ) > 0 )/* next pid */
{
if ( pid == my_pid )/* ignore myself */
continue ;;
pname = get_pname ( pid ) ;
if ( strcmp ( my_name , pname ) == 0 )
kill ( pid , SIGKILL ) ;/* send the kill signal */
}
if ( pid < 0 ) /* no process found - ERROR
*/
return ;/* (must have found myself)
*/
}
/**/
char *get_pname ( pid_t pid ) /* find program name from
pid */
{ /* use /proc//stat */
FILE *stt ;/* stat virtual file Handel
*/
static char pname [256] , *none = "" ; /* program name is < 256
chars */
char *nbeg, *nend ;/* temp pointer */
/* structure of 1st and only line of /proc//stat
pid (name) stt . name is the exact disk name (upper case under DOS)
1300 (bash) S 1 1300 1300 1280
1988 (SLeeP-TsT) S 1 1988 1988 1280*/
sprintf ( pname , "/proc/%d/stat" , pid ) ; /* stat file name */
stt = fopen ( pname , "rt" ) ; /* try to open */
if ( stt == NULL )
{
return ( none ) ; /* no name (error signal) */
}
fgets ( pname , 256 , stt ) ; /* read 1st (only) line from
stat */
fclose ( stt ) ;/* close "stat", no check */
if ( ( nbeg = strchr ( pname , '(' ) ) == NULL )/* search "(" before name */
{
return ( none ) ; /* no name (error signal) */
}
if ( ( nend = strchr ( nbeg , ')' ) ) == NULL ) /* search ")" after name */
{
return ( none ) ; /* no name (error signal) */
}
*nend = 0 ; /* cap it */
return ( ++ nbeg ) ;/* 1st char of program name
*/
}
/*=*/
pid_t next_pid ( int cont )/* get next pid */
{ /* cont = 0 - start new
search */
static DIR *hdir = NULL ; /* handle for open directory
*/
struct dirent *dent ; /* directory entry pointer */
#define FPID ( dent->d_name ) /* PID as file name pointer
*/
if ( cont == 0 )/* new search */
{
if ( hdir != NULL ) /* a search in progress ? */
closedir ( hdir ) ; /* close directory (no
check) */
if ( ( hdir = opendir ( "/proc" ) ) == NULL ) /* open directory
"/proc" */
{
fprint