Search code examples
cunixlockingfcntl

how to lock a file so that other process cannot cat it?


#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    struct flock fl;
    fl.l_start = 0;
    fl.l_len = 517; //found the size of the file outside (not best practise, I know)
    fl.l_whence = SEEK_SET;
    int fd = open("test", O_RDWR);
    if(fd<0)
        perror("open");
    
    fl.l_type = F_RDLCK;
    fl.l_pid = getpid();
    if(fcntl(fd, F_SETLK, &fl) < 0)
    {
        perror("fcntl"); //geting fcntl: Invalid argument
        exit(1);
    }
    
    if(fl.l_type != F_UNLCK)
    {
        printf("file has been exclusively locked by process:%u\n",fl.l_pid);
        printf("press enter to release the file\n");
        getchar();
        fl.l_type = F_UNLCK; //file released
    }
}

I would like to lock a file (test), which contain lorem ipsum (some random text), so that other process could not cat it until the currect process release the lock. But which argument passed to fcntl is wrong?

EDIT: After comments I have initialized some members of fl variable (see edits), no, despite working. I can still cat the locked file test in another process... why, when it is locked?


Solution

  • File locking is not mandatory locking — it is advisory locking.

    That means that if a program such as cat does not look to see whether a file is locked, it doesn't matter whether some other program locks it or not — cat will still read the file.

    Unless you use a variant of cat that does check for file locks, you are not going to be able to use file locking to stop cat.

    What can you do instead?

    1. Rename the file.
    2. Change permissions on the file.
    3. Decide not to worry about it.

    The last option is the easiest — and probably most effective.

    Some systems do support mandatory file locking. Typically, that's indicated by setting the SGID bit on a non-executable file. If you're using such a system, then you should be able to prevent cat from working on a locked file.