Concernant le problème, l'erreur venait du mode opératoire en deux points:
*tout d'abord vim ne tient pas compte des verrous, pour vérifier que le verrou est posé, il suffit en réalité d'éxécuter deux fois le processus en même temps.
*la fonction lock_is_set() ne permet pas de vérifier à postériori si le processus a lui même posé un verrou, car un processus peut toujours poser un verrou à la place d'un verrou dont il est le propriétaire. C'est pour cette raison qu'elle renvoyait 0 dans tous les cas.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "lock.h"
int main ( int argc , char** argv )
{
int fd;
char tab[4] = "ab\n";
if ( chdir ( "/tmp" ) < 0 )
{
perror ( "[main.c] chdir(0)" );
exit ( EXIT_FAILURE );
}
fd = open ( "fic_test.tmp" , O_RDWR | O_CREAT , S_IRWXU );
if ( fd < 0 )
{
perror ( "[main.c] open(0)" );
exit ( EXIT_FAILURE );
}
if ( lock_file ( fd , LOCK_NOWAIT ) < 0 )
{
perror ( "[main.c] lock_file(0)" );
exit ( EXIT_FAILURE );
}
if ( lseek ( fd , 0 , SEEK_END ) < 0 )
{
perror ( "[main.c] lseek(0)" );
exit ( EXIT_FAILURE );
}
printf ( "Press <RETURN> to continue\n" );
getchar ( );
if ( write ( fd , &tab[0] , 3 ) < 0 )
{
perror ( "[main.c] write(0)" );
exit ( EXIT_FAILURE );
}
if ( lock_file ( fd , LOCK_UNLOCK ) < 0 )
{
perror ( "[main.c] lock_file(1)" );
exit ( EXIT_FAILURE );
}
if ( close ( fd ) < 0 )
{
perror ( "[main.c] close(0)" );
exit ( EXIT_FAILURE );
}
exit ( EXIT_SUCCESS );
}
lock.c
//--------------------------------------------------------------------
//--------------------------------------------------------------------
/* Lib Name : file.c
* Ver : 1.0
* Description : Provide basic functions to
* manipulate files.
*/
//--------------------------------------------------------------------
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include "lock.h"
//--------------------------------------------------------------------
/* Function Name : lock_file
* Object : Lock an opened file.
* Input Parameters : [int] fd = File descriptor of the file.
* [int] cmd = kind of lock to apply.
* Output Parameters : [int] = - '-1' if error.
* - '0' if no error.
* Functions called : fcntl().
*/
//-------------------------------------------------------------------
int lock_file ( int fd , int cmd )
{
struct flock lock;
/* Setup an exclusive (writing) lock */
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
/* Apply the lock */
if ( cmd == LOCK_NOWAIT )
{
lock.l_type = F_WRLCK;
return fcntl ( fd , F_SETLK , &lock );
}
else if ( cmd == LOCK_WAIT )
{
lock.l_type = F_WRLCK;
return fcntl ( fd , F_SETLKW , &lock );
}
else if ( cmd == LOCK_UNLOCK )
{
lock.l_type = F_UNLCK;
return fcntl ( fd , F_SETLK , &lock );
}
else
{
/* Invalid argument */
errno = EINVAL;
return -1;
}
}
//--------------------------------------------------------------------
/* Function Name : lock_is_set
* Object : Check if an opened file is locked
* by AN OTHER processus.
* Input Parameters : [int] fd = File descriptor of the file.
* Output Parameters : [int] = - the pid of the process which locked it.
* - '0' if unlocked.
* - '-1' if error;
* Functions called : fcntl().
*/
//-------------------------------------------------------------------
int lock_is_set ( int fd )
{
struct flock lock;
/* Test an exclusive (writing) lock */
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
/* Apply the lock and check the result */
if ( fcntl ( fd , F_GETLK , &lock ) < 0 )
return -1;
else if ( lock.l_type == F_UNLCK )
return 0;
else
/* lock.l_pid is now the pid of the process
* owner of the lock */
return lock.l_pid;
}
Massez moi les pieds.