Philippe A.
Philippe A.

Reputation: 2955

Why fcntl never returns an error when trying to unlock a file?

I have written a simple program helping me to test fcntl file locking. Argument 'set' locks my test file. Argument 'get' tells me if the file is locked or not. Argument 'un' tries to unlock the file.

In one shell, I run the program to lock the file. I keep the file open and wait for enter.

$ ./lock set
file is locked
hit enter to release lock with a call to fcntl

In the other shell, I run the program to lock the file. It does not work because the file is already locked. I run the program to check the lock. I'm told the lock is not available. All this works as expected.

$ ./lock get
locking is not possible
$ ./lock set
locking file failed

What happens if I try unlocking my file in shell two? It seems fcntl never returns me an error when called with l_type = F_UNLCK.

$ ./lock un
unlocked
file either was successfully unlocked or was already unlocked
$ ./lock get
locking is not possible
$ ./lock set
locking file failed

I know my unlocking code is good. If I go back in shell one and let the program unlock:

$ ./lock set
file is locked
hit enter to release lock with a call to fcntl

unlocked
hit enter to close the file

I can confirm the result in shell two:

$ ./lock get
locking is possible

I am only using exclusive write lock on the entire file:

  fl.l_type = F_WRLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;
  fl.l_pid = -1; // used by F_GETLK only

  result = fcntl(fd, F_SETLK, &fl);

Here's how I'm doing the unlock:

  fl.l_type = F_UNLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;
  fl.l_pid = -1; // used by F_GETLK only

  result = fcntl(fd, F_SETLK, &fl);
  if (!result)
  {
    printf("unlocked\n");
  }

I am working on RHEL 5.5.

Can you explain this fcntl behavior? Thanks!

EDIT: The man page seems to imply that the unlocking operation is meant to be used by the lock owner only: "As well as being removed by an explicit F_UNLCK, record locks are automatically released when the process terminates or if it closes any file descriptor referring to a file on which locks are held."

Upvotes: 1

Views: 1346

Answers (2)

geekosaur
geekosaur

Reputation: 61459

More to the point, that's what POSIX specifies them doing. It's far from the only, or even the most dubious, decision they made concerning file locks (the latter would be that all locks, system-wide, on a given file must be dropped when any process with a file descriptor open on the file close()s it).

Upvotes: 0

Brian Roach
Brian Roach

Reputation: 76918

Because ... that's the way it works?

On Unix systems, locks are advisory. You use them by attempting to obtain a lock, and only doing what you want if you succeed.

This includes unlocking the file. Since the whole system is voluntary, nothing prevents you from unlocking a file from another process, and therefore your program always succeeds at doing so.

Upvotes: 1

Related Questions