Открываем файл,

User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Наверное, я плохой рассказчик - чтото никто не может понять что надо.
Есть файл, который открывается программой и туда постоянно пишется инфо.
Если удалить файл после того как программа открыла файл, программа пишущая в файл понятия об етом иметь не будет, а хотелось бы. Или чтоб его удалить было нельзя.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

A. Fig Lee wrote:Есть файл, который открывается программой и туда постоянно пишется инфо. Если удалить файл после того как программа открыла файл, программа пишущая в файл понятия об етом иметь не будет, а хотелось бы. Или чтоб его удалить было нельзя.

А почему уже упоминавшееся решение c chmod не подходит? Также можно перед закрытием файла убедиться, что его имя в директории не изменилось (я, правда, не знаю, есть ли в POSIX API, который позволяет это делать по открытому хендлу.) Если же оно изменилось, то произвести какие-то осмысленные действия. Например, попробовать переименовать его в исходное имя.
Cheers
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

A. Fig Lee wrote:Наверное, я плохой рассказчик - чтото никто не может понять что надо.
Есть файл, который открывается программой и туда постоянно пишется инфо.
Если удалить файл после того как программа открыла файл, программа пишущая в файл понятия об етом иметь не будет, а хотелось бы. Или чтоб его удалить было нельзя.


You can just backup the file name and then attempt to restore it on the program completion:

Code: Select all

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
  if (link("a.dat", "a.dat.bck") == -1)
    {printf("Could not create a backup name: %d\n", errno); exit(2);}
  sleep(10);
  if (rename("a.dat.bck", "a.dat") == -1) {
    if (errno == EEXIST) unlink("a.dat.bck");
    else printf("Error renaming : %d\n", errno);
  }
}

oracle@staging1>gcc -o b b.c
ls - l > a.dat
oracle@staging1>./b &
[1] 9959
oracle@staging1>rm a.dat
[1]+  Done                    ./b
oracle@staging1>ls -l a.dat
-rw-r--r--   1 oracle   dba          562 May  9 19:05 a.dat


VC
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

tengiz wrote:
A. Fig Lee wrote:Есть файл, который открывается программой и туда постоянно пишется инфо. Если удалить файл после того как программа открыла файл, программа пишущая в файл понятия об етом иметь не будет, а хотелось бы. Или чтоб его удалить было нельзя.

А почему уже упоминавшееся решение c chmod не подходит? Также можно перед закрытием файла убедиться, что его имя в директории не изменилось (я, правда, не знаю, есть ли в POSIX API, который позволяет это делать по открытому хендлу.) Если же оно изменилось, то произвести какие-то осмысленные действия. Например, попробовать переименовать его в исходное имя.


'chmod' protects the file contents but it does not protect the file name which is a separate entity (a directory entry).

VC
User avatar
Pink Panther
Уже с Приветом
Posts: 3811
Joined: 14 Oct 2001 09:01

Post by Pink Panther »

A. Fig Lee wrote:Прекрасно. Вернемся к оригинальному вопросу - как выловить что файл был "rm-ed"?
Единственно приходит в голову - периодически чекать директори ентри.


Какой кошмар, ну прямо каменный век какой-то! :wink: А вот в Windows :lol: :umnik1: есть замечательная фунция ReadDirectoryChangesW, которая сама все изменения рапортует. В юниксе наверняка есть что-то подобное.
User avatar
VladDod
Уже с Приветом
Posts: 56113
Joined: 06 May 2001 09:01

Post by VladDod »

A. Fig Lee wrote:Если порядка 100 записей в секунду. 100 раз открывать-закрывать?

Всего то? А запись длинная? Ежели проверять на наличие файла перед каждой записью, то получится то же самое, что переоткрывать его. Я, честно говоря, не вижу проблемы. Закрытие файла после каждой записи еще и гарантирует относительную безопасность уже выведенных данных ... ну, скажем, в случае крэша проги-писалки.

А так да ... получется только сбоку смотреть ... жив ли файл. Иначе, файла - нет, писалка уверенно пишет и куда все это девается - непонятно.
в реале супруги редко бывают друзьями, так как их отношения подпорчены сексом (с)Роза
Плавали-Знаем! (C)
User avatar
VladDod
Уже с Приветом
Posts: 56113
Joined: 06 May 2001 09:01

Post by VladDod »

Как вариант ... сделать внутренний буфер ... к примеру на 100-200-1000 записей и открывать-закрывать файл однократно на моменты заполнения буфера. Сбрасывая все оптом.
в реале супруги редко бывают друзьями, так как их отношения подпорчены сексом (с)Роза
Плавали-Знаем! (C)
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

tengiz wrote: Также можно перед закрытием файла убедиться, что его имя в директории не изменилось (я, правда, не знаю, есть ли в POSIX API, который позволяет это делать по открытому хендлу.) Если же оно изменилось, то произвести какие-то осмысленные действия. Например, попробовать переименовать его в исходное имя.

That's best idea so far. Thanks.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

VladDod wrote: Ежели проверять на наличие файла перед каждой записью, то получится то же самое, что переоткрывать его. Я, честно говоря, не вижу проблемы. Закрытие файла после каждой записи еще и гарантирует относительную безопасность уже выведенных данных ... ну, скажем, в случае крэша проги-писалки.

А так да ... получется только сбоку смотреть ... жив ли файл. Иначе, файла - нет, писалка уверенно пишет и куда все это девается - непонятно.

Я не собираюсь проверять перед каждой записью, а скажем раз в секунду.
Но в принципе, если краш, данные могут потерятся.
Закрытие файла не гарантирует флашинг его на диск. sync/fsync гарантируют или открытие файла с флагом O_SYNC
Верить нельзя никому - даже себе. Мне - можно!
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

VladDod wrote:Как вариант ... сделать внутренний буфер ... к примеру на 100-200-1000 записей и открывать-закрывать файл однократно на моменты заполнения буфера. Сбрасывая все оптом.

Не годится. Если краш - все теряется. Скорее всего для надежности иметь еще процесс который открытием файла инкрементирует коунтер оф линков в директори ентри, ну и kонтролировать ету директори ентри каждую например секунду.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Post by f_evgeny »

tengiz wrote:
f_evgeny wrote:Не вернет, для процесса открытый файл так и остается существующим до его (процесса), конца работы. Это по генеральной Юниксовой линии так. И так и должно быть!

А в чём причина, почему это так однозначно правильно?

P.S. Отдельный вопрос-подколка - а почему Вы специально выбираете фразеологию Съездов КПСС? :)

1. Это не однозначно правильно, а правильно для Юниксов, в Виндовсе - свои правильности.
2. Ну, на мой взгляд, это так сделано для того, чтобы зря не тратить ресурсы, а также руководствуясь принципом KISS. Ну еще исходя из того, что это многопользователская система с самого начала, да еще ориентированнная на максимальную автоматизаццию рутинных задач.

PS - просто это шутка N 21 (C), причем на мой взгляд ассоциативно и с некоторой толикой юмора (надеюсь) отражает положение вещей. Даже можно сказать, что это не генеральная линия, а так написано в трудах основоположников. Могу сказать и по другому - так в Юниксе концептуально заложено с самого начала.
User avatar
zor0n
Уже с Приветом
Posts: 630
Joined: 01 May 2001 09:01
Location: Москва -> New York

Post by zor0n »

А нельзя, чтобы записывающий протсесс периодически по stat проверял, что мета-данные файла не изменились? Не очень эффективно, но жить можно.

Кроме того (раньше, по крайней мере), в системах, порожденных от SVR4 был mandatory locking посредством установки SGID в атрибутах каталога файла.

Тем не менее, самое лучшее - это попытаться переформулировать задачу. Почему чужой процесс вообще должен удалять файл, который кому-то нужен. Это у Вас "IPC" так реализован или clean-up? Есть другие, более удобные способы. :umnik1:
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

zor0n wrote:А нельзя, чтобы записывающий протсесс периодически по stat проверял, что мета-данные файла не изменились? Не очень эффективно, но жить можно.


Чето типа етого я и думаю сделать. Онако директори локинг было бы идеал.
Кроме того (раньше, по крайней мере), в системах, порожденных от SVR4 был mandatory locking посредством установки SGID в атрибутах каталога файла.

Мы ето весь топик обсуждали, что ето не играет рояли для rm
Тем не менее, самое лучшее - это попытаться переформулировать задачу. Почему чужой процесс вообще должен удалять файл, который кому-то нужен. Это у Вас "IPC" так реализован или clean-up? Есть другие, более удобные способы. :umnik1:

Не должен и не процесс. Но все может быть - ктонибудь может взять и удалить.
Какие более удобные способы? Изменения аккаунтов под которым бежит демон, пермишнс и т.д. не щитается - ето другая область, тоже будем делать, но надо бы программным путем локнуть.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Post by f_evgeny »

A. Fig Lee wrote:
zor0n wrote:А нельзя, чтобы записывающий протсесс периодически по stat проверял, что мета-данные файла не изменились? Не очень эффективно, но жить можно.


Чето типа етого я и думаю сделать. Онако директори локинг было бы идеал.
Кроме того (раньше, по крайней мере), в системах, порожденных от SVR4 был mandatory locking посредством установки SGID в атрибутах каталога файла.

Мы ето весь топик обсуждали, что ето не играет рояли для rm
Тем не менее, самое лучшее - это попытаться переформулировать задачу. Почему чужой процесс вообще должен удалять файл, который кому-то нужен. Это у Вас "IPC" так реализован или clean-up? Есть другие, более удобные способы. :umnik1:

Не должен и не процесс. Но все может быть - ктонибудь может взять и удалить.
Какие более удобные способы? Изменения аккаунтов под которым бежит демон, пермишнс и т.д. не щитается - ето другая область, тоже будем делать, но надо бы программным путем локнуть.

Так может Вам не прекратить работу надо после удаления файла, а восстановить файл вместе с записанными даннми при завершении, как было до удаления?
И потом, кто кроме root-а может удалить Ваш файл?
User avatar
Fielder
Уже с Приветом
Posts: 695
Joined: 26 Mar 1999 10:01
Location: Moscow -> Rockville, MD -> Muenchen

Post by Fielder »

Pink Panther wrote:
A. Fig Lee wrote:Прекрасно. Вернемся к оригинальному вопросу - как выловить что файл был "rm-ed"?
Единственно приходит в голову - периодически чекать директори ентри.


Какой кошмар, ну прямо каменный век какой-то! :wink: А вот в Windows :lol: :umnik1: есть замечательная фунция ReadDirectoryChangesW, которая сама все изменения рапортует. В юниксе наверняка есть что-то подобное.



Линух умеет dnotify.
Да ето, что-то анологичное
Du glaubst zu schieben, und du wirst geschoben. (c) Goethe
vc
Уже с Приветом
Posts: 664
Joined: 05 Jun 2002 01:11

Post by vc »

Fielder wrote:
Pink Panther wrote:
A. Fig Lee wrote:Прекрасно. Вернемся к оригинальному вопросу - как выловить что файл был "rm-ed"?
Единственно приходит в голову - периодически чекать директори ентри.


Какой кошмар, ну прямо каменный век какой-то! :wink: А вот в Windows :lol: :umnik1: есть замечательная фунция ReadDirectoryChangesW, которая сама все изменения рапортует. В юниксе наверняка есть что-то подобное.



Линух умеет dnotify.
Да ето, что-то анологичное


Linux has the proprietary (non-POSIX) F_NOTIFY fcntl extension that allows it to notify the program about directory changes:

Code: Select all

fcntl(fd, F_SETSIG, SIGRTMIN);
fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);


... which other Unixes, Sorais being one of those, do not support.


VC
DMG
Новичок
Posts: 57
Joined: 05 May 2001 09:01
Location: SPb -> Michigan

Post by DMG »

zor0n wrote:А нельзя, чтобы записывающий протсесс периодически по stat проверял, что мета-данные файла не изменились? Не очень эффективно, но жить можно.


Just thinking: why couldn't the inode number of the handle associated with the open (and possibly deleted by other program) file be compared against inode number obtained by opening (read-only) of the same file by its name?

Then if both inode numbers match then nothing happened; if they differ: the open file was unlinked from the directory, and new one created with new inode number; or the second inode number may be absent: then the file was unlinked and no new file created. At least this must be portable to every UNIX having stat and fstat.
Dimitry
User avatar
zor0n
Уже с Приветом
Posts: 630
Joined: 01 May 2001 09:01
Location: Москва -> New York

Post by zor0n »

A. Fig Lee wrote:
zor0n wrote:Тем не менее, самое лучшее - это попытаться переформулировать задачу. Почему чужой процесс вообще должен удалять файл, который кому-то нужен. Это у Вас "IPC" так реализован или clean-up? Есть другие, более удобные способы. :umnik1:


Не должен и не процесс. Но все может быть - ктонибудь может взять и удалить.
Какие более удобные способы? Изменения аккаунтов под которым бежит демон, пермишнс и т.д. не щитается - ето другая область, тоже будем делать, но надо бы программным путем локнуть.


Так не бывает. просто так файлы никто удалять не станет. Чтобы покоцать файл, всегда необходимо намерение. Как правило, ето один из нижеследующих вариантов:

- Файл пишется в "чужую" область (например, в чужой домашний каталог или в /етц/маил е т.п.) Выход очевиден: создайте "свой" каталог и пишите в него.

- Файл пишется в /tmp и удаляется "мусорщиком." Мусорщики во всех "нормальных" системах удаляют файлы из /tmp только если к ним не было доступа в течение определенного периода времени (1 месяц?). Выход - пишите чаще.

- Файл лежит в "своем" каталоге (напр. в /var/lib/myprogram/ или /var/run/myprogram/) и его все-равно кто-то убивает. Ето уже проблем административная: кому-то явно нечего делать. Вы, например, не будете писать программу, которая удаляет файл, не принадлежащий вам, правильно? Выход: поймать пользователя данного процесса и удалить у него что-нибудь. :nono#:

Я бы начал решать вопрос в етом аксепте, а не техническом. :umnik1:
User avatar
tengiz
Уже с Приветом
Posts: 4468
Joined: 21 Sep 2000 09:01
Location: Sammamish, WA

Post by tengiz »

Злостный оффтопик.

f_evgeny wrote:2. Ну, на мой взгляд, это так сделано для того, чтобы зря не тратить ресурсы, а также руководствуясь принципом KISS. Ну еще исходя из того, что это многопользователская система с самого начала, да еще ориентированнная на максимальную автоматизаццию рутинных задач.

PS - просто это шутка N 21 (C)..., причем на мой взгляд ассоциативно и с некоторой толикой юмора (надеюсь) отражает положение вещей. Даже можно сказать, что это не генеральная линия, а так написано в трудах основоположников. Могу сказать и по другому - так в Юниксе концептуально заложено с самого начала.

По-моему в основоположных трудах основоположников (в числе которых есть человек с символической фамилией Ossanna :)) нет ничего ни о многопользовательских системах, ни о разделении времени. Это уже значительно более поздняя ересь и мутация. Во всяком случае именно так следует из первых опубликованных основоположниками академических трудов на тему UNIX.

Юмор, конечно, понятен - а что за копирайт на шутку N 21?
Cheers
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

Фиг Ли, упомяни операционку что ли.
Во многих Юнихах есть нотификация, FreeBSD, Linux.
Вопрос, а нельзя ли заставить удаляющую программу проверять не открыт ли файл кем то и отказываться удалять если открыт.
Тебе что то вроде LogRotate нужно?
С нотификацией у меня нет уверенности (на любой системе включая Вин) что между действием и обработкой сообщения не пройдет какое то время за которое пишущая прога что то не накидает в удаленный файл. Так что решать надо комплексно.
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

f_evgeny wrote:Так может Вам не прекратить работу надо после удаления файла, а восстановить файл вместе с записанными даннми при завершении, как было до удаления?
И потом, кто кроме root-а может удалить Ваш файл?

Может. Ето еще лучше. Как минимум надо детект ситуацию.
2. Ну откуда ж я знаю? Стоять может в разных местах, че там за порядки - не знаю. Нужна дурак-пруф система.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

zor0n wrote:Так не бывает. просто так файлы никто удалять не станет. Чтобы покоцать файл, всегда необходимо намерение. Как правило, ето один из нижеследующих вариантов:

- Файл пишется в "чужую" область (например, в чужой домашний каталог или в /етц/маил е т.п.) Выход очевиден: создайте "свой" каталог и пишите в него.

- Файл пишется в /tmp и удаляется "мусорщиком." Мусорщики во всех "нормальных" системах удаляют файлы из /tmp только если к ним не было доступа в течение определенного периода времени (1 месяц?). Выход - пишите чаще.

- Файл лежит в "своем" каталоге (напр. в /var/lib/myprogram/ или /var/run/myprogram/) и его все-равно кто-то убивает. Ето уже проблем административная: кому-то явно нечего делать. Вы, например, не будете писать программу, которая удаляет файл, не принадлежащий вам, правильно? Выход: поймать пользователя данного процесса и удалить у него что-нибудь. :nono#:

Я бы начал решать вопрос в етом аксепте, а не техническом. :umnik1:

1. Бывает. Сам случайно удалял. Рука на ентер соскочила.
2. Меня ето никто не спрашивает. Где работать будет и кто что делать будет - не мое дело. Мое дело - чтоб работало как положено.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Strannik223 wrote:Фиг Ли, упомяни операционку что ли.
Во многих Юнихах есть нотификация, FreeBSD, Linux.

"Да купи ж ты лотерею!" (с). В смысле в самом начале написал - Solaris 8.

Вопрос, а нельзя ли заставить удаляющую программу проверять не открыт ли файл кем то и отказываться удалять если открыт.

Каким образом? сабститюте "rm"?
Система то не наша!
Тебе что то вроде LogRotate нужно?

Нет. Для етого BSD-жный syslog годится.
С нотификацией у меня нет уверенности (на любой системе включая Вин) что между действием и обработкой сообщения не пройдет какое то время за которое пишущая прога что то не накидает в удаленный файл. Так что решать надо комплексно.

Да лучше поздно чем никогда.
Мне бы директорию локнуть.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

А может так: при открытии файла создаем hardlink с каки нибудь "мусорным названием" а при закрытии проверяем, если орининал не был удален шаловливыми ручками то удаляем hardlink а если наш файл убили, то переименовываем hardlinked file to original name. Только надо бы предусмотреть зачистку hardlink-ов которые остаются в результате крешей.
Правда остается возможной диверсия: кто то удалил файл и создал новый с таким же именем.
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Strannik223 wrote:А может так: при открытии файла создаем hardlink с каки нибудь "мусорным названием" а при закрытии проверяем, если орининал не был удален шаловливыми ручками то удаляем hardlink а если наш файл убили, то переименовываем hardlinked file to original name. Только надо бы предусмотреть зачистку hardlink-ов которые остаются в результате крешей.
Правда остается возможной диверсия: кто то удалил файл и создал новый с таким же именем.


Good. Very good. Very brilliant idea. Будем щупать. Thanks. :gen1:
Верить нельзя никому - даже себе. Мне - можно!

Return to “Вопросы и новости IT”