Автоматически удалять файлы, созданные библиотекой, когда она убита - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть динамическая библиотека Linux, которая должна создавать временные файлы. Эти файлы должны иметь имя файла - они не могут быть созданы и немедленно удалены из ссылки. Я также не могу перехватить сигналы типа SIGINT и SIGKILL, потому что это библиотека, используемая другими программами.

Есть ли вменяемый способ автоматического удаления файлов при уничтожении создавшего их процесса?

Разъяснения:

  1. Это действительно мои ограничения. Пожалуйста, не отвечайте, сказав «вы можете unlink()», когда я только что сказал в вопросе, что я не могу unlink().
  2. Я понимаю, что для этого потребуется поддержка ОС - очевидно, что когда моя программа будет убита, она не сможет запустить любой код для удаления файлов. Но может быть какой-то способ пометить файлы, чтобы ОС их удалила.

Например, в Windows есть опция «удалить при закрытии» , которая означает, что когда ваша программа уничтожена, все открытые файлы закрываются и автоматически удаляются (я думаю; я не пробовал). Нечто подобное в теории явно возможно в Linux, если такая функциональность где-то существует. Я просто хочу знать, так ли это.

Ответы [ 5 ]

0 голосов
/ 04 сентября 2018

Другое возможное решение - fork() дочерний процесс. Затем отправьте все ваши временные имена файлов этому процессу через некоторый механизм.

Дочерний процесс может зарегистрироваться, чтобы знать, когда его родитель убит так:

#include <sys/prctl.h>
int ret;
ret = prctl (PR_SET_PDEATHSIG, SIGUSR1);
if (ret)
        perror ("prctl");

И тогда он получит SIGUSR1, когда родитель будет убит. В этот момент он может удалить файлы в обычном режиме.

0 голосов
/ 04 сентября 2018

Создайте файл, затем передайте /proc/self/fd/X в LLVM, где X - ваш файловый дескриптор. Теперь вы можете отменить связь (как предполагает Базиль),

Поскольку /proc/self исчезает только при закрытии вашей программы, имя и, следовательно, файл живут достаточно долго.

0 голосов
/ 04 сентября 2018

Нет, вы не можете удалить их после того, как программа, использующая вашу библиотеку, не запущена, потому что программа, использующая ее, больше не работает.

Вместо этого вы, вероятно, должны либо

  • Проверка наличия устаревших / превышающих размер / оставшихся временных файлов при нормальной работе вашей библиотеки (очищается при следующем запуске)
  • Создайте отдельную программу, которая управляет этим для вас (периодически очищается)

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

Как этот пост по теме ставит

SIGKILL вытаскивает коврик из вашего рабочего процесса, немедленно прерывая его.

0 голосов
/ 04 сентября 2018

Хотя это не особенно разумно, Linux позволяет вам также передавать имена удаленных файлов через / proc / $ pid / fd / $ number.

0 голосов
/ 04 сентября 2018

У меня есть динамическая библиотека Linux, которая должна создавать временные файлы.

Вы можете использовать atexit (3) , чтобы зарегистрировать обработчик, который будет удалять все эти временные файлы в exit (3) раз (или обычное завершение main). Конечно, это не будет работать с сигналами.

Вы можете создать эти файлы в некоторой файловой системе tmpfs. Тогда они будут удалены при выключении.

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

Есть ли вменяемый способ автоматического удаления файлов при уничтожении создавшего их процесса?

В общем, не (и не может быть с семантикой файлов POSIX). Вы можете написать программу очистки (возможно, используя inotify (7) средства) для запуска извне (например, как crontab задание или как какой-то демон).

Вы также можете отсоединить (2) каждый такой временный файл после создания (с помощью open или creat) и сохранить для него дескриптор файла. Затем, когда процесс завершается или когда он close -с этим дескриптором файла, файловый ресурс освобождается. Этот трюк используется tmpfile (3) .

Кстати, если вы используете LLVM в качестве JIT-транслятора, вы можете рассмотреть возможность использования libgccjit . Он способен генерировать код без какого-либо входного файла.

Такие временные файлы не могут быть удалены автоматически, потому что некоторые другие процессы могут открыть их (по их имени) - в любой момент. И именно поэтому в Linux не может быть «удаления при закрытии» (в отличие от этого, по слухам, Windows позволяет только одному процессу записать данный файл).

Но может быть какой-то способ пометить файлы, чтобы ОС их удалила.

Нет, не в Linux или POSIX. Эта функция должна быть предоставлена ​​кодом приложения.

...