Comment verrouiller et déverrouiller le fichier pid avec «fcntl ()»

Je fais une recherche sur le net et même sur le stackoverflow afin de trouver un exemple d’utilisation de fcntl() pour verrouiller et déverrouiller le fichier pid "/var/run/myapp.pid" mais je n’ai pas trouvé d’exemple clair pour cela.

Pourriez-vous me fcntl() un exemple d’utilisation de fcntl() pour verrouiller et déverrouiller le fichier pid?

Le verrou ne doit pas être bloqué (si le fichier est déjà verrouillé)

Comme vous avez tagué Linux, verbatim forme man lockf (souligné par moi):

Sous Linux, lockf () n’est qu’une interface au-dessus du locking de fcntl (2) . De nombreux autres systèmes implémentent lockf () de cette manière, mais notez que POSIX.1-2001 laisse la relation entre les verrous lockf () et fcntl (2) non spécifiés. Une application portable devrait probablement éviter de mélanger des appels à ces interfaces.

En cherchant dans les sources glibc actuelles ( eglibc-2.11.3/io/lockf.c ), une utilisation possible de fcntl() pour implémenter le locking ressemble à ceci:

 /* Copyright (C) 1994,1996,1997,1998,2000,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redissortingbute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is dissortingbuted in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include  #include  #include  #include  #include  /* lockf is a simplified interface to fcntl's locking facilities. */ int lockf (int fd, int cmd, off_t len) { struct flock fl; memset ((char *) &fl, '\0', sizeof (fl)); /* lockf is always relative to the current file position. */ fl.l_whence = SEEK_CUR; fl.l_start = 0; fl.l_len = len; switch (cmd) { case F_TEST: /* Test the lock: return 0 if FD is unlocked or locked by this process; return -1, set errno to EACCES, if another process holds the lock. */ fl.l_type = F_RDLCK; if (__fcntl (fd, F_GETLK, &fl) < 0) return -1; if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ()) return 0; __set_errno (EACCES); return -1; case F_ULOCK: fl.l_type = F_UNLCK; cmd = F_SETLK; break; case F_LOCK: fl.l_type = F_WRLCK; cmd = F_SETLKW; break; case F_TLOCK: fl.l_type = F_WRLCK; cmd = F_SETLK; break; default: __set_errno (EINVAL); return -1; } /* lockf() is a cancellation point but so is fcntl() if F_SETLKW is used. Therefore we don't have to care about cancellation here, the fcntl() function will take care of it. */ return __fcntl (fd, cmd, &fl); } 

Quelques mods sont nécessaires pour faire cette compilation:

  • remplace __fcntl par fcntl
  • remplace __set_errno() par errno =

.. et deuxièmement, que cela devienne async-signal-save:

  • remplacez l'appel à memset() par les affectations appropriées à la variable struct fcntl .