Как проверить, был ли файл открыт другим приложением в C ++? - PullRequest
9 голосов
/ 26 июня 2009

Я знаю, что в C ++ есть функция is_open(), но я хочу, чтобы одна программа проверяла, не был ли файл открыт другим приложением. Есть ли способ сделать это с помощью стандартной библиотеки?

РЕДАКТИРОВАТЬ - Уточнил в ответах, что это для приложения Linux.

Ответы [ 9 ]

4 голосов
/ 26 июня 2009

Нет, стандартная библиотека не имеет такой функциональности.

3 голосов
/ 26 июня 2009

Мало того, что стандартная библиотека не имеет этой функциональности, это вообще невозможно. Вы можете (в Linux) проверить /proc/*/fd & mdash; но возможно, что ваша программа не имеет разрешения делать это на процессах других пользователей (например, в Ubuntu по умолчанию).

2 голосов
/ 18 ноября 2010

Следующий код может работать.

int main(int argc, char ** argv)
{
    int fd = open(argv[1], O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    if (fcntl(fd, F_SETLEASE, F_WRLCK) && EAGAIN == errno) {
        puts("file has been opened");
    }
    else {
        fcntl(fd, F_SETLEASE, F_UNLCK);
        puts("file has not been opened");
    }

    close(fd);
    return 0;
}
2 голосов
/ 26 июня 2009

Если вы контролируете другой процесс (имеете исходный код), лучший план - использовать консультативные блокировки в обоих процессах. Эта блокировка определена в POSIX и будет переносимой во всех операционных системах.

В Linux вы можете использовать утилиту lsof , чтобы увидеть, какие файлы открываются другими процессами.

Это ограничено тем, для чего у вас есть разрешения - вы должны выполнить проверку как привилегированный пользователь, или вы получите результаты только для файлов, открытых тем же пользователем, что и тот, который выполняет проверку.

Я знаю только об утилите командной строки, а не о каком-либо системном вызове, который вы можете использовать непосредственно из кода C.

В Linux также возможно включить обязательную блокировку для данной файловой системы (mount -o mand) и установить специальные флаги для файла (chmod g-x, g + s). Затем, когда ваш процесс попытается получить блокировку записи, он потерпит неудачу, если другой процесс откроет файл. Это вряд ли когда-либо используется, но если вы полностью управляете рассматриваемой системой, это может быть вариантом.

1 голос
/ 26 июня 2009

Возможно, вы могли бы просто попытаться получить полную блокировку записи? Он потерпит неудачу, если кто-то еще откроет его для чтения или записи.

fopen("myfile.txt", "r+")

Если это не кроссплатформенный и Win32, то вы можете запросить еще более детальный набор блокировок.

См. здесь и посмотрите на dwShareMode, значение 0, а также другие параметры.

0 голосов
/ 26 июня 2009

В Windows этот маленький и грязный трюк сработает (если файл существует и у вас есть необходимые разрешения)

  if (  0 != rename("c:/foo.txt", "c:/foo.txt")  ) {
     printf("already opened\n");
  }

Это может работать и в Linux.

0 голосов
/ 26 июня 2009

Как говорит @Neil Butterworth, стандартная библиотека этого не делает.

В Unix вы можете использовать fcntl для блокировки файлов.

Вы можете написать обертку для вашей функции open, которая проверяет блокировку (и блокирует, если ее нет) файл, если он открыт никем другим. Вы также должны написать оболочку для close, которая освобождает блокировку для закрытия файла.

0 голосов
/ 26 июня 2009

Не родным способом, вы можете вызвать Sysinternals 'handle.exe в качестве крайней меры ...

0 голосов
/ 26 июня 2009

Неа. Если только другое приложение не использует консультативные блокировки.

См. http://docs.sun.com/app/docs/doc/816-0213/6m6ne37v5?a=view

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...