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/pid/stat you may use /proc/pid/exename (this
does not exist on UNIX, and /proc/pid/exe needs root permission).
Ehud.
- proc fs searching -
#include string.h
#include stdio.h
#include stdlib.h
#include unistd.h
#include dirent.h
#include sys/types.h
#include signal.h/* for kill */
char *get_pname ( pid_t pid ) ;/* find program name from pid
returns program name or
uses /proc/pid/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/pid/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/pid/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