Как я могу определить, когда файл отправляется в корзину, используя Kqueue?

Я работаю с Kqueues в mac os x и пытаюсь отслеживать папку, поэтому я использовал фильтр EVFILT_VNODE и хочу получать уведомление всякий раз, когда файл удаляется, я пробовал NOTE_DELETE, но он обнаруживает только когда файл удаляется через unlink() system call, но не при перемещении файла в корзину.

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


person user3742053    schedule 01.08.2015    source источник


Ответы (1)


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

Таким образом, вы должны следить за NOTE_RENAME, чтобы узнать, когда файл перемещается/переименовывается. Затем вы можете использовать fcntl(fd, F_GETPATH, buffer), чтобы узнать новый путь. Обратите внимание, что для файла с жесткой ссылкой это может дать путь к одной из других ссылок, а не путь к элементу, как его представляет себе пользователь. Однако это должно быть довольно редко.

Затем вам нужно будет увидеть, находится ли новый путь внутри корзины. Это тоже сложно.

Если вам может потребоваться OS X 10.10 или более поздняя версия, вы можете использовать [[NSFileManager defaultManager] getRelationship:&relationship ofDirectory:NSTrashDirectory inDomain:0 toItemAtURL:[NSURL fileURLWithPath:pathFromFcntl] error:NULL]. Если этот метод возвращает значение true и устанавливает для relationship значение, отличное от NSURLRelationshipOther, файл был перемещен в корзину.

Если вам нужно поддерживать версии 10.9 и более ранние, вам придется сделать это вручную:

Там не только один каталог мусора. Для каждого пользователя на каждом томе существует отдельный каталог. Чтобы найти каталог корзины, который будет использовать конкретный файл, вызовите [[NSFileManager defaultManager] URLForDirectory:NSTrashDirectory inDomain:NSUserDomainMask appropriateForURL:[NSURL fileURLWithPath:pathFromFcntl] create:NO error:NULL].

Затем вам нужно определить, находится ли новый путь где-то в этом каталоге (а не только непосредственно внутри него). Вам нужно перебрать каталоги пути. Для каждого каталога используйте -[NSURL getResourceValue:forKey:error:] с NSURLFileResourceIdentifierKey в качестве ключа, чтобы получить его идентификатор ресурса. Получите то же значение для каталога мусора. Сравните два, используя -isEqual:. Если вы найдете каталог-предок, идентификатор ресурса которого совпадает с идентификатором каталога корзины, то файл находится в корзине. Если итерация каталогов-предков достигает корня, не обнаруживая этого, то это не так.

person Ken Thomases    schedule 02.08.2015