/* code is derived from Samba
   Copyright (C) Andrew Tridgell 1992-1998
   Copyright (C) Jeremy Allison 2001
   Copyright (C) Simo Sorce 2001


   modification herein Copyright 2002 Li-Cheng Tai
   This code is covered by the GNU General Public License, version 2 or later */
   
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/wait.h>
/*******************************************************************
A fcntl wrapper that will deal with EINTR.
********************************************************************/

int sys_fcntl_ptr(int fd, int cmd, void *arg)
{
    int ret;

    do {
            ret = fcntl(fd, cmd, arg);
    } while (ret == -1 && errno == EINTR);
    return ret;
}

int fcntl_lock(int f, uint64_t offset, uint64_t count)
{
    struct flock lock;
    int ret;
    
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = offset;
    lock.l_len = count;
    lock.l_pid = 0;

    ret = sys_fcntl_ptr(f,F_SETLK,&lock);
    if (ret == -1)
    {
        fprintf(stderr, "lock failed with error: %s\n", strerror(errno));
        exit(1);
    }
    else
    {
        lock.l_type = F_UNLCK;
        lock.l_whence = SEEK_SET;
        lock.l_start = offset;
        lock.l_len = count;
        lock.l_pid = 0;
        ret = sys_fcntl_ptr(f,F_SETLK,&lock);
        if (ret == -1)
        {
            fprintf(stderr, "unlock failed with error: %s\n", strerror(errno));
            exit(1);
        }
    }
    return 1;
}

int main(int argc, char *argv[])
{
    int f, i, status;
    
    
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s file_name \n", argv[0]);
    }
    f = open(argv[1], O_CREAT | O_RDWR);
    if (!f)
    {
        fprintf(stderr, "unlock failed with error: %s\n", strerror(errno));
        exit(1);
    }
    while (1)
    {
        i = fork();
        if (i > 0)
        {
            sleep(2);
            wait(&status);
            continue;
        }
        else
        {
            fcntl_lock(f, 2147483539L, 1);
            exit(0);
        }
    }
    close(f);
    return 0;
}
