/* lock.c - handle file locking
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include <errno.h>
#include "lock.h"


/* Apply or remove an advisory lock on "fd". See flock(2).
 *
 * TODO: get this working over NFS
 */
int my_flock(char *file, int fd, int operation)
{
#if 0
	return (flock(fd, operation));
#endif
	struct flock lock;
	int i;

	lock.l_type = F_WRLCK;
	if (operation == LOCK_UN)
		lock.l_type = F_UNLCK;
	lock.l_whence = SEEK_END;
	lock.l_start = 0;
	lock.l_len = 0;
	i = fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
	if (i == -1)
		if ((errno == EAGAIN) || (errno == EACCES))
			errno = EWOULDBLOCK;

#if 0
	printf("i=%d,fd=%d,op=%d,file='%s',err=%s\n", i, fd, operation,
	       file, strerror(errno));
#endif

	return (i);

#if 0
	int i;

	switch (operation) {		    /* this code from cron3.0pl1/compat.c */

	case LOCK_SH:			    /* get a shared lock */
	case LOCK_EX:			    /* get an exclusive lock */
		i = lockf(fd, F_LOCK, 0);
		break;

	case LOCK_SH | LOCK_NB:	    /* get a non-blocking shared lock */
	case LOCK_EX | LOCK_NB:	    /* get a non-blocking exclusive lock */
		i = lockf(fd, F_TLOCK, 0);
		if (i == -1)
			if ((errno == EAGAIN) || (errno == EACCES))
				errno = EWOULDBLOCK;
		break;

	case LOCK_UN:			    /* unlock */
		i = lockf(fd, F_ULOCK, 0);
		break;

	default:			    /* can't decipher operation */
		i = -1;
		errno = EINVAL;
		break;
	}

	printf("i=%d,fd=%d,op=%d,file='%s',err=%s\n", i, fd, operation,
	       file, strerror(errno));
	return (i);
#endif
}

/* EOF */
