Search code examples
c++clinux

Proper way to lock file for renaming/deleting in linux


Let's say I have a file on Linux and it's currently opened by one of my processes. The user can rename it, delete it, etc. Basically - they can modify it. Is there any way to prevent them doing that? At the same time - the application has to have an access to read/write data from the file, so I can't lock it out completely and make it immutable.


Solution

  • Proper way to lock file for renaming/deleting in linux

    Using flock, normally. This requires co-operation between users since it's an advisory locking mechanism. That means that it doesn't actually prevent changes; it only prevents others from obtaining a lock.


    You seem assume that files and directory entries are the same thing, but they are separate entities. A file refers to data on disk, and a directory entry is name that references a file.[1]

    You also seem to assume that every file has exactly one directory entry referencing it, but it can have more than one of them, or none at all.

    As such, it unclear what you are trying to protect from modification:

    • The file.
    • A directory entry that references the file.
    • All directory entries that reference the file.

    Either way, you can't.

    • If you can open the file for writing or otherwise obtain a write/append handle to the file, you can modify it.
    • If you can modify the directory contains the directory entry that references the file, you can rename or delete that directory entry. (Even if you don't have access to the file.)
    • If you can open the file for writing, you can create a new directory entry for it. There's no way to obtain a list of all directory entries that reference a file without scanning the entire volume.

    So, short of ensuring the process is the only one with access to the file or directory entry through file permissions, you can't prevent modifications to the file or directory entry.


    If you want a temporary private file, a common trick is to create a file then delete its directory entry (i.e. unlink it). The file will continue to exist (without a name) until the file handle (and every dup of it) is closed.


    1. These are very simple definitions that are good enough for our purposes here.