Skip to content

Incorrect handling of lock modification by FLOCK. #185

Open
@kpan2034

Description

@kpan2034

According to the flock man page (https://linux.die.net/man/2/flock):

A process may only hold one type of lock (shared or exclusive) on a file. Subsequent flock() calls on an already locked file will convert an existing lock to the new lock mode.

This results in the following expected behavior:

  • When a process that has a shared lock calls flock again to acquire an exclusive lock, it is able to upgrade the lock to an exclusive lock.
  • When a process that has an exclusive lock calls flock again to acquire a shared lock, it is able to downgrade it to a shared lock as well

The Lind implementation of flock differs here: instead of modifying the lock, it waits to be able to acquire it.
You can see this difference in behavior by running the following program.

#undef _GNU_SOURCE
#define _GNU_SOURCE

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

#define FILE "test.txt"

int main(int argc, char **argv) {
  // Create a file to use
  int fd = open(FILE, O_RDWR | O_CREAT, 0777);
  if (fd == -1) {
    perror("OPEN FAILED\n");
    exit(EXIT_FAILURE);
  }

  int lock;

  // Obtain a shared lock on the file
  lock = flock(fd, LOCK_SH);
  if (lock == -1) {
    perror("LOCK FAILED\n");
    exit(EXIT_FAILURE);
  }

  // Upgrade the lock to an exclusive lock
  lock = flock(fd, LOCK_EX);
  if (lock == -1) {
    perror("LOCK FAILED\n");
    exit(EXIT_FAILURE);
  }

  // Release the lock
  lock = flock(fd, LOCK_UN);
  if (lock == -1) {
    perror("LOCK FAILED\n");
    exit(EXIT_FAILURE);
  }

  printf("OK\n");
  fflush(stdout);

  // Close file before removing
  close(fd);
  return 0;
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions