Sujet : [C Linux] Pose de verrou via fcntl()
Bah ouais, une colle pas évidente, pour s'assurer que y'a pas que des gifs d'anal fucking mais aussi du brainstorming sur l'asile.
Alors voila le topo les cracks:
J'ai crée un programme pour me familiariser avec les verrous.
Mon mode opératoire est le suivant, je crée et verrouille un fichier "socket.tmp" dans le repertoire /tmp, puis je mets le programme en pause (getchar).
J'ouvre ce fichier avec l'éditeur vim et je tente d'écrire dessus pour vérifier que le verrou soit bien installé. Or je peux écrire sans problème sur le fichier alors qu'il devrait être vérrouillé.
Si j'ouvre le fichier en lecture seulement, le fcntl() ne veut pas le verrouiller en écriture, ce qui me laisse supposer que fcntl() tente bien la pose de verrou.
La fonction is_locked_socket() censée vérifier que le verrou est présent rapporte dans tous les cas que le fichier n'est pas verrouillé !
=> J'en conclu que fcntl() démarre la pose du verrou mais cette dernière n'aboutie pas. fcntl() ne renvoit pourtant aucun message d'erreur.
Le code n'est pas coloré par le forum, donc payes tes yeux à l'arrivée.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <socket.h>
#include <unistd.h>
const char test[3]="ab";
int main ( int argc , char** argv )
{
int fd;
chdir ( "/tmp" );
if ( ( fd = open_socket ( "socket.tmp" ) ) < 0 )
{
printf ( "Cannot create socket file\n" );
exit ( -1 );
}
printf ( "Press <RETURN> to set lock\n" );
getchar ();
if ( lock_socket ( fd ) < 0 )
{
printf ( "Cannot lock socket file\n" );
exit ( -1 );
}
printf ( "Lock Status = %d\n" , is_locked_socket ( fd ) );
lseek ( fd , 0 , SEEK_END );
write ( fd , &test[0] , 2 );
printf ( "Press <RETURN> to remove lock\n" );
getchar ();
if ( unlock_socket ( fd ) < 0 )
exit ( -1 );
if ( close_socket ( fd ) < 0 )
exit ( -1 );
exit ( EXIT_SUCCESS );
socket.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "socket.h"
#include <stdio.h>
//--------------------------------------------------------------------
/* Function Name : open_socket
* Object : Opens an existing socket or creates it !
* Input Parameters : [char*] path = Name of the socket file.
* Output Parameters : [int] = File descriptor of the socket file.
* '-1' if error.
* Functions called : open(),lseek().
*/
//--------------------------------------------------------------------
int open_socket ( char* path )
{
int err, fd;
/* OPEN the file */
fd = open ( path , O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR );
if ( fd < 0 )
return SOCKET_ERROR;
/* JUMP at the beginning of the file */
err = lseek ( fd , 0 , SEEK_SET );
if ( err < 0 )
return SOCKET_ERROR;
return fd;
}
//--------------------------------------------------------------------
/* Function Name : close_socket
* Object : Close an existing socket.
* Input Parameters : [int] fd = File descriptor of the socket file.
* Output Parameters : [int] = exit status.
* '-1' if error.
* '0' if no error.
* Functions called : close().
*/
int close_socket ( int fd )
{
return close ( fd );
}
//--------------------------------------------------------------------
/* Function Name : unlock_socket
* Object : Unlock an existing socket.
* Input Parameters : [int] fd = File descriptor of the socket file.
* Output Parameters : [int] = exit status.
* '-1' if error.
* '0' if no error.
* Functions called : fcntl().
*/
//-------------------------------------------------------------------
int unlock_socket ( int fd )
{
static struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
return fcntl ( fd , F_SETLKW , &lock );
}
//--------------------------------------------------------------------
/* Function Name : lock_socket
* Object : Lock an existing socket.
* Input Parameters : [int] fd = File descriptor of the socket file.
* Output Parameters : [int] = exit status.
* '-1' if error.
* '0' if no error.
* Functions called : fcntl().
*/
//-------------------------------------------------------------------
int lock_socket ( int fd )
{
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
return fcntl ( fd , F_SETLKW , &lock );
}
//--------------------------------------------------------------------
/* Function Name : is_locked_socket
* Object : Check if an existing socket is locked.
* Input Parameters : [int] fd = File descriptor of the socket file.
* Output Parameters : [int] = exit status.
* the pid of the process if locked.
* '0' if unlocked.
* '-1' if error;
* Functions called : fcntl().
*/
//-------------------------------------------------------------------
int is_locked_socket ( int fd )
{
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if ( fcntl ( fd , F_GETLK , &lock ) == -1 )
return -1;
if ( lock.l_type == F_UNLCK )
return 0;
else
return lock.l_pid;
}
Aller les mecs.