Locking file in cygwin

2005-04-26 Thread Vladislav Grinchenko
Hi,

I am new to cygwin (and win32 programming in general), so if the answer
to my question is covered somewhere else, please point me in the right
direction.

While porting one of my c++ libraries to cygwin, I stumbled over this:

Calling fcntl (fd, F_GETLK, ...) returns ENOSYS (function not
implemented).

I searched the archive and couldn't find anything appropriate to explain
why.
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.

One more thing, I don't need backward compatability if that is the case.
My target platforms are WinXP and Win2000.

Thanks in advance,
-Vlad

--
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple
Problem reports:   http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ:   http://cygwin.com/faq/



RE: Locking file in cygwin

2005-04-26 Thread Dave Korn
Original Message
From: Vladislav Grinchenko
Sent: 26 April 2005 14:22


 While porting one of my c++ libraries to cygwin, I stumbled over this:
 
 Calling fcntl (fd, F_GETLK, ...) returns ENOSYS (function not
 implemented).
 
 I searched the archive and couldn't find anything appropriate to explain
 why.


  Because the function has not been implemented!


cheers,
  DaveK
-- 
Can't think of a witty .sigline today


--
Unsubscribe info:  http://cygwin.com/ml/#unsubscribe-simple
Problem reports:   http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ:   http://cygwin.com/faq/



Re: Locking file in cygwin

2005-04-26 Thread Ehud Karni
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