Добрый день!
Возник такой вопрос, к сожалению срочный.
Надеюсь на вашу помощь :-))Нужно подправить стандартную утилиту script
(jоткрывает файл, форкает шелл, а в файл пишет всё, что попадает на консоль) таким образом, что бы юзер из этого фооркнутого шелла не мог удалить/исправить этот файл.Иначе говоря, как открыть файл на запись так, что бы пока он открыт, его нельзя было бы менять из другого процесса.
Всем спасибо за идеи заранее.
Поставить блокировку на запись другим процессам на весь или часть файла.
Спасибо, но не мог бы ты чуть пояснить?Я нашел только flock.
Говорю ему - flock(_мой_файл_, LOCK_EX);
- не помогает... из шела файл легко удаляется...
Не та функция - не тот параметр? /dev/руки ?Linux 2.4.8-26mdksmp #1 SMP Sun Sep 23 16:04:21 CEST 2001 i686 unknown
А какой процесс у тебя пишет в файл, родительский или дочерний?
И когда ты создаёшь блокировку, до fork'a или после?Дело в том, что блокировки не наследуются дочерними процессами (с соотв. выводами).
А вызов правильный.
Всего есть три процесса.
1-й, в нём открывается файл, я его тут же лочу.
2-й и 3-й - дети первого.
Мне надо, чтобы из 3-го файл был не доступен.
А он доступен и из первого, и pp второго (он туда пишет), и из третьего! Где-то что то не так.>А какой процесс у тебя пишет
>в файл, родительский или дочерний?
>
>И когда ты создаёшь блокировку, до
>fork'a или после?
>
>Дело в том, что блокировки не
>наследуются дочерними процессами (с соотв.
>выводами).
>А вызов правильный.
>Всего есть три процесса.
>1-й, в нём открывается файл, я
>его тут же лочу.
>2-й и 3-й - дети первого.
>
А что делают процессы?
1-й: ...
2-й: ...
3-й: ...если 1-й не живёт всё время работы 2-го и 3-его - то и блокировки не будет
>А что делают процессы?
>1-й: ...
Открывает файл, оределяет переменные среды, разбирает параметры командной строки, форкает от себя 2-й и 3-й процесс.
>2-й: ...
Превращается в шелл, который прописан у юзера как SHELL
>3-й: ...Вот тут я до конца не догнал - не то они оба дети 1-го, не то 3-й - дитё первого, перехватывает ввод-вывод, пишет его в файл, а 2-й форкнут от него, а не от первого.
>если 1-й не живёт всё время
>работы 2-го и 3-его -
>то и блокировки не будетДа в том то и дело - первый живёт, и если его убить, слетают и остальные, если убить 3-й, то слетает и 2-й. Вообще-то там кода всего на ~350 строк, это стандартная утилитка, называется script.
Только сейчас понял всю свою тупость... :(1) flock (...) и fcntl (fd, F_SETLK, ...) не годятся, поскольку обеспечивают "мягкие" блокировки файлов (или записей в файлах). Т.е. если другой процесс тоже использует эту технику блокировки, то всё хорошо. А если нет - то другому процессу просто плевать, что кто-то "заблокировал" этот файл.
2) Есть вариянт блокировки основанный на fchmod ()
int fd = open ("./file.lck", O_RDWR);
if (fd < 0)
{
return -1;
}fchmod (fd, 0);
for (int i = 1; i < 50; i++)
if (write (fd, "abra", 4) != 4)
{
return -2;
}
else sleep (1);fchmod (fd, 0666);
... но если владелец файла является твоим юзером, то никто не может ему помешать поменять права на файл chmod-ом и изменить/удалить его.
3) Единственный выход возможен если процесс стартует из-под другого пользователя (root)
а) стартуем процесс и открываем лог-файл
б) владелец файла должен быть root, а права,
например 0600
в) fork-аемся и в процессе, который будет шеллом, меняем UID и GID.
Круто. Спасибо.
Позволю себе не согласиться ( из man fcntl )
...
F_SETLK
Set or clear a file segment lock according to the lock
description pointed to by the third argument, arg,
taken as a pointer to type struct flock, defined in
<fcntl.h>. F_SETLK is used to establish shared (or
read) locks (F_RDLCK) or exclusive (or write) locks
(F_WRLCK), as well as to remove either type of lock
(F_UNLCK). F_RDLCK, F_WRLCK and F_UNLCK are defined in
<fcntl.h>. If a shared or exclusive lock cannot be
set, fcntl() will return immediately with a return
value of -1.
...Иначе говоря, если
struct flock v;
v.l_type = F_WRLCK;
...
fcntl( fd, F_SETLK, &v )
...
есть ничто иное, как ИСКЛЮЧАЮЩАЯ блокировка на файл. Объем блокирования определяется в структуре v.
ЗЫЖ Игра правами, имхо - кривенько как-то.
>ЗЫЖ Игра правами, имхо - кривенько
>как-то.Класс! Но ...
Есть такие определения блокировок:
"advisory locking" и "mandatory locking"Первое определение - это "мягкие" блокировки, на которые др. процессам можно наплевать.
Второе - файл действительно блокируется для записи независимо от того проверяет ли процесс наличие блокировки или нет.
Хочу огорчить, но fcntl ( ... F_SETLK ...) не гарантирует, что для блокировки на запись будет использован механизм "mandatory locking". Всё зависит от конкретной ОС.
Например, наследники Sys V _обычно_ обеспечивают механизм "mandatory locking", а наследники BSD/BSDI - нет.
Для меня остаётся вопрос: как обеспечить "mandatory locking" в ОС, где fcntl ( ... F_SETLK ...) не использует этот вид блокировок?
Я не огорчусь :). Мне это все интересно только с познавательной точки зрения - я работаю на соляре да и юзал-то их пару раз, где-то в телнетных приложениях. Кстатиь и солярка когда-то давно родилась из бсдёвого ядра. Вот что интересно и непонятно - а КАКОЙ СМЫСЛ в блокировке , если на нее можно положить? Или стандарт P[ortable]OSIX считает блокировки ненужными? Хотя это уже словоблудие.
Что до твоего вопроса - на "ваших" ядрах тоже работает ORACLE. А эти ребята юзают блокировки в полный рост. Не рылся, но можно рискнуть, при наличии свободного времени, платформы и исходников.
ЗЫЖ У них там некоторые вещи собираются аж на ассемблере, так что может они что-то хитрое :) склепали.
man flock гласит:
...
NOTES
Use of these interfaces should be restricted to only appli-
cations written on BSD platforms. Use of these interfaces
with any of the system libraries or in multi-thread applica-
tions is unsupported.
...
Поэтому юзай fcntl. Ман соответствующий или у Чана глянь.
ЗЫЖ Примера нету под рукой...
У меня ман соляркин.