2

I am trying to understand POSIX file-region locks in C. The program below is really simple, sets the lock to F_WRLCK and then gets locks. There is no errors during opening/setting lock. Unfortunatelly it's always returning F_UNLCK. Where is the mistake ? Is it possible that it doesnt work on OSX correctly ?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
void printLockType(int lock) {
    if ( lock == F_RDLCK ) {
            printf("readlock %i \n", lock);
    }else if ( lock == F_WRLCK ) {
            printf("writelock %i \n", lock);
    }else if ( lock == F_UNLCK ) {
            printf("unlock %i \n", lock);
    } else {
            printf("other %i\n", lock);
    }
} 
int main(int argc, char *argv[])
{    
    int fd;
    struct flock fl ,fl2;

    fl2.l_type   = F_RDLCK;  /* read/write lock */
    fl2.l_whence = 0; /* beginning of file */
    fl2.l_start  = 0;        /* offset from l_whence */
    fl2.l_len    = 100;        /* length, 0 = to EOF */
    fl2.l_pid    = getpid();

    fl.l_type   = F_WRLCK;  /* read/write lock */
    fl.l_whence = 0; /* beginning of file */
    fl.l_start  = 0;        /* offset from l_whence */
    fl.l_len    = 1000;        /* length, 0 = to EOF */
    fl.l_pid    = getpid();

    if ((fd = open("xxx", O_RDWR)) == -1) {
        perror("open");
        exit(1);
    }


    if (fcntl(fd, F_SETLK, &fl) == -1) {
        perror("fcntl");
        exit(1);
    }

    if(fcntl(fd, F_GETLK, &fl2) == -1) {
        printf("%s \n", strerror(errno));
    } else {
        printLockType(fl2.l_type);
    }

    return 0;
}
Wojtek338
  • 43
  • 4
  • 1
    Just a clarification: The "locks" you're talking about are not part of C but is defined by [the POSIX standard](https://en.wikipedia.org/wiki/POSIX). – Some programmer dude Mar 19 '17 at 09:22

1 Answers1

3

You're misunderstanding the F_GETLK query. It returns F_UNLCK when nothing blocks the calling process from placing a lock of the given type at the given position.

Since the calling process is the one that created these existing locks, it can also create this new lock.


The Mac OS X manuals say

 F_GETLK 

Get the first lock that blocks the lock description pointed to by the third argument, arg, taken as a pointer to a struct flock (see above). The information retrieved overwrites the information passed to fcntl in the flock structure. If no lock is found that would prevent this lock from being created, the structure is left unchanged by this function call except for the lock type which is set to F_UNLCK.