/*	$NetBSD: k_flock.c,v 1.2 1997/01/09 06:09:01 tls Exp $	*/

#include "krb_locl.h"

#define K_OP_MASK (K_LOCK_SH | K_LOCK_EX | K_LOCK_UN)

int
k_flock(fd, operation)
	int fd;
	int operation;
{
#ifdef HAVE_FLOCK
  int op = 0;
  if (operation & K_LOCK_SH)
    op |= LOCK_SH;
  if (operation & K_LOCK_EX)
    op |= LOCK_EX;
  if (operation & K_LOCK_UN)
    op |= LOCK_UN;
  if (operation & K_LOCK_NB)
    op |= LOCK_NB;

  return flock(fd, op);
#else /* !HAVE_FLOCK */
  struct flock arg;
  int code, cmd;
  
  arg.l_whence = SEEK_SET;
  arg.l_start = 0;
  arg.l_len = 0;		/* means to EOF */

  if (operation & K_LOCK_NB)
    cmd = F_SETLK;
  else
    cmd = F_SETLKW;		/* Blocking */

  switch (operation & K_OP_MASK) {
  case K_LOCK_UN:
    arg.l_type = F_UNLCK;
    code = fcntl(fd, F_SETLK, &arg);
    break;
  case K_LOCK_SH:
    arg.l_type = F_RDLCK;
    code = fcntl(fd, cmd, &arg);
    break;
  case K_LOCK_EX:
    arg.l_type = F_WRLCK;
    code = fcntl(fd, cmd, &arg);
    break;
  default:
    errno = EINVAL;
    code = -1;
    break;
  }
  return code;
#endif /* !HAVE_FLOCK */
}
