2013-06-07 4 views
4

Я делаю повторную проверку в сети и даже на стеке, чтобы найти пример использования fcntl(), чтобы заблокировать и разблокировать файл pid "/var/run/myapp.pid", но я не нашел ясного пример для этого.Как заблокировать и разблокировать файл pid с помощью «fcntl()»

Не могли бы вы указать мне пример с помощью fcntl(), чтобы заблокировать и разблокировать файл pid?

замок не должен быть заблокирован (если файл настроек уже заблокирован)

ответ

3

Как помечено Linux, дословная форма man lockf (курсив мной):

В Linux lockf() - это просто интерфейс сверху fcntl (2) блокировка. Многие другие системы реализуют lockf() таким образом, но обратите внимание, что POSIX.1-2001 оставляет связь между lockf() и fcntl (2) замки неуказанные. Возможно, переносное приложение должно избегать смешивания вызовов с этими интерфейсами.

Так, глядя на источники тока GLibC (eglibc-2.11.3/io/lockf.c) возможное использование fcntl() реализовать блокирующие выглядят следующим образом:

/* 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 redistribute 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 distributed 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 <sys/types.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <string.h> 

/* 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); 
} 

Несколько модов необходимы, во-первых сделать это компиляция:

  • заменить __fcntl на fcntl
  • заменить __set_errno(<errno-define>) на errno = <errno-define>

.. а во-вторых, чтобы он стал асинхронному сигнал сохранения:

  • заменить вызов memset() с соответствующими assigments к переменной struct fcntl.
+0

Итак, если я разработаю свою собственную функцию 'lockf()', например, ее имя будет 'async_lockf()'. И затем я копирую в этой функции содержимое указанной функции, и я делаю изменения, которые вы указали. то новая функция 'async_lockf()' будет функцией async-signal-save, а затем я могу использовать ее в обработчике sigaction. это правда ? – MOHAMED

+1

для 'memset()': я изменю его на: 'struct flock fl = {0}' – MOHAMED

+0

@MOHAMED: Кажется, да, да. Но я предпочитаю не называть его чем-то вроде '* lockf *', поскольку на самом деле это не относится к 'lockf()', а просто имитирует его поведение. Однако: Вы знаете, что это код GPLed, не так ли? – alk

 Смежные вопросы

  • Нет связанных вопросов^_^