/*  CSC238 
 *  Author: W. James MacLean
 *  Example of file locking using fcntl()
 */

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>

void flock(FILE *fp)
{
  flock_t fl = { F_WRLCK, SEEK_SET, 0, 0};
  assert(fp != (FILE *)NULL);

  if (fcntl(fileno(fp), F_SETLKW, &fl) == -1)
  {
    perror("flock: error in fcntl");
    exit(1);
  }
}

void funlock(FILE *fp)
{
  flock_t fl = { F_UNLCK, SEEK_SET, 0, 0};
  assert(fp != (FILE *)NULL);

  if (fcntl(fileno(fp), F_SETLK, &fl) == -1)
  {
    perror("funlock: error in fcntl");
    exit(1);
  }
}

int ftrylock(FILE *fp)
{
  flock_t fl = { F_WRLCK, SEEK_SET, 0, 0 };
  assert(fp != (FILE *)NULL);

  if (fcntl(fileno(fp), F_SETLK, &fl) != -1) return 0 ;
  else
    switch (errno)
    {
      case EACCES:
      case EAGAIN:
        return 1 ; /* unable to get lock */
      default:
        perror("ftrylock: error in fcntl");
        exit(1);
    }
}

