/* flock.cc.  NT specific implementation of advisory file locking.

   This file is part of Cygwin.

   This software is a copyrighted work licensed under the terms of the
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
   details. */

/* The basic mechanism as well as the datastructures used in the below
   implementation are taken from the FreeBSD repository on 2008-03-18.
   The essential code of the lf_XXX functions has been taken from the
   module src/sys/kern/kern_lockf.c.  It has been adapted to use NT
   global namespace subdirs and event objects for synchronization
   purposes.

   So, the following copyright applies to most of the code in the lf_XXX
   functions.

 * Copyright (c) 1982, 1986, 1989, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Scooter Morris at Genentech Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      @(#)ufs_lockf.c 8.3 (Berkeley) 1/6/94
*/

/*
 * The flock() function is based upon source taken from the Red Hat
 * implementation used in their imap-2002d SRPM.
 *
 * $RH: flock.c,v 1.2 2000/08/23 17:07:00 nalin Exp $
 */

/* The lockf function is based upon FreeBSD sources with the following
 * copyright.
 */
/*
 * Copyright (c) 1997 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Klaus Klein.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "winsup.h"
#include <assert.h>
#include <sys/file.h>
#include <unistd.h>
#include <stdlib.h>
#include "cygerrno.h"
#include "security.h"
#include "shared_info.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "pinfo.h"
#include "sigproc.h"
#include "cygtls.h"
#include "tls_pbuf.h"
#include "miscfuncs.h"
#include "ntdll.h"
#include <sys/queue.h>
#include <wchar.h>

#define F_WAIT 0x10	/* Wait until lock is granted */
#define F_FLOCK 0x20	/* Use flock(2) semantics for lock */
#define F_POSIX	0x40	/* Use POSIX semantics for lock */

#ifndef OFF_MAX
#define OFF_MAX LLONG_MAX
#endif

static NO_COPY muto lockf_guard;

#define INODE_LIST_LOCK()	(lockf_guard.init ("lockf_guard")->acquire ())
#define INODE_LIST_UNLOCK()	(lockf_guard.release ())

#define LOCK_DIR_NAME_FMT	L"flock-%08x-%016X"
#define LOCK_DIR_NAME_LEN	31	/* Length of the resulting name */
#define LOCK_DIR_NAME_DEV_OFF	 6	/* Offset to device number */
#define LOCK_DIR_NAME_INO_OFF	15	/* Offset to inode number */

/* Don't change format without also changing lockf_t::from_obj_name! */
#define LOCK_OBJ_NAME_FMT	L"%02x-%01x-%016X-%016X-%016X-%08x-%04x"
#define LOCK_OBJ_NAME_LEN	69	/* Length of the resulting name */

#define FLOCK_INODE_DIR_ACCESS	(DIRECTORY_QUERY \
				 | DIRECTORY_TRAVERSE \
				 | DIRECTORY_CREATE_OBJECT \
				 | READ_CONTROL)

#define FLOCK_EVENT_ACCESS	(EVENT_QUERY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)

/* This function takes the own process security descriptor DACL and adds
   SYNCHRONIZE permissions for everyone.  This allows all processes
   to wait for this process to die when blocking in a F_SETLKW on a lock
   which is hold by this process. */
static void
allow_others_to_sync ()
{
  static NO_COPY bool done;

  if (done)
    return;

  NTSTATUS status;
  PACL dacl;
  LPVOID ace;
  ULONG len;

  /* Get this process DACL.  We use a rather small stack buffer here which
     should be more than sufficient for process ACLs.  Can't use tls functions
     at this point because this gets called during initialization when the tls
     is not really available.  */
#define MAX_PROCESS_SD_SIZE	3072
  PISECURITY_DESCRIPTOR sd = (PISECURITY_DESCRIPTOR) alloca (MAX_PROCESS_SD_SIZE);
  status = NtQuerySecurityObject (NtCurrentProcess (),
				  DACL_SECURITY_INFORMATION, sd,
				  MAX_PROCESS_SD_SIZE, &len);
  if (!NT_SUCCESS (status))
    {
      debug_printf ("NtQuerySecurityObject: %y", status);
      return;
    }
  /* Create a valid dacl pointer and set its size to be as big as
     there's room in the temporary buffer.  Note that the descriptor
     is in self-relative format. */
  BOOLEAN present, defaulted;
  RtlGetDaclSecurityDescriptor (sd, &present, &dacl, &defaulted);
  if (!present) /* If so, dacl has undefined value. */
    {
      dacl = (PACL) (sd + 1);
      RtlCreateAcl (dacl, MAX_PROCESS_SD_SIZE - sizeof *sd, ACL_REVISION);
    }
  else if (dacl == NULL) /* Everyone has all access anyway */
    {
      done = true;
      return;
    }
  else
    {
      dacl->AclSize = MAX_PROCESS_SD_SIZE - ((PBYTE) dacl - (PBYTE) sd);
    }
  /* Allow everyone to SYNCHRONIZE with this process. */
  status = RtlAddAccessAllowedAce (dacl, ACL_REVISION, SYNCHRONIZE,
				   well_known_world_sid);
  if (!NT_SUCCESS (status))
    {
      debug_printf ("RtlAddAccessAllowedAce: %y", status);
      return;
    }
  /* Set the size of the DACL correctly. */
  status = RtlFirstFreeAce (dacl, &ace);
  if (!NT_SUCCESS (status))
    {
      debug_printf ("RtlFirstFreeAce: %y", status);
      return;
    }
  dacl->AclSize = (char *) ace - (char *) dacl;
  /* Write the DACL back. */
  status = NtSetSecurityObject (NtCurrentProcess (), DACL_SECURITY_INFORMATION, sd);
  if (!NT_SUCCESS (status))
    {
      debug_printf ("NtSetSecurityObject: %y", status);
      return;
    }
  done = true;
}

/* Get the handle count of an object. */
static ULONG
get_obj_handle_count (HANDLE h)
{
  OBJECT_BASIC_INFORMATION obi;
  NTSTATUS status;
  ULONG hdl_cnt = 0;

  status = NtQueryObject (h, ObjectBasicInformation, &obi, sizeof obi, NULL);
  if (!NT_SUCCESS (status))
    debug_printf ("NtQueryObject: %y", status);
  else
    hdl_cnt = obi.HandleCount;
  return hdl_cnt;
}

/* Helper struct to construct a local OBJECT_ATTRIBUTES on the stack. */
struct lockfattr_t
{
  OBJECT_ATTRIBUTES attr;
  UNICODE_STRING uname;
  WCHAR name[LOCK_OBJ_NAME_LEN + 1];
};

/* Per lock class. */
class lockf_t
{
  public:
    uint16_t	    lf_flags; /* Semantics: F_POSIX, F_FLOCK, F_WAIT */
    uint16_t	    lf_type;  /* Lock type: F_RDLCK, F_WRLCK */
    off_t	    lf_start; /* Byte # of the start of the lock */
    off_t	    lf_end;   /* Byte # of the end of the lock (-1=EOF) */
    int64_t         lf_id;    /* Cygwin PID for POSIX locks, a unique id per
				 file table entry for BSD flock locks. */
    DWORD	    lf_wid;   /* Win PID of the resource holding the lock */
    uint16_t	    lf_ver;   /* Version number of the lock.  If a released
				 lock event yet exists because another process
				 is still waiting for it, we use the version
				 field to distinguish old from new locks. */
    class lockf_t **lf_head;  /* Back pointer to the head of the lockf_t list */
    class inode_t  *lf_inode; /* Back pointer to the inode_t */
    class lockf_t  *lf_next;  /* Pointer to the next lock on this inode_t */
    HANDLE	    lf_obj;   /* Handle to the lock event object. */

    lockf_t ()
    : lf_flags (0), lf_type (0), lf_start (0), lf_end (0), lf_id (0),
      lf_wid (0), lf_ver (0), lf_head (NULL), lf_inode (NULL),
      lf_next (NULL), lf_obj (NULL)
    {}
    lockf_t (class inode_t *node, class lockf_t **head,
	     short flags, short type, off_t start, off_t end,
	     long long id, DWORD wid, uint16_t ver)
    : lf_flags (flags), lf_type (type), lf_start (start), lf_end (end),
      lf_id (id), lf_wid (wid), lf_ver (ver), lf_head (head), lf_inode (node),
      lf_next (NULL), lf_obj (NULL)
    {}
    ~lockf_t ();

    bool from_obj_name (class inode_t *node, class lockf_t **head,
			const wchar_t *name);

    /* Used to create all locks list in a given TLS buffer. */
    void *operator new (size_t size, void *p)
    { return p; }
    /* Used to store own lock list in the cygheap. */
    void *operator new (size_t size)
    { return cmalloc (HEAP_FHANDLER, sizeof (lockf_t)); }
    /* Never call on node->i_all_lf! */
    void operator delete (void *p)
    { cfree (p); }

    POBJECT_ATTRIBUTES create_lock_obj_attr (lockfattr_t *attr,
					     ULONG flags, void *sd_buf);

    void create_lock_obj ();
    bool open_lock_obj ();
    void close_lock_obj () { NtClose (lf_obj); lf_obj = NULL; }
    void del_lock_obj (HANDLE fhdl, bool signal = false);
};

/* Per inode_t class */
class inode_t
{
  friend class lockf_t;

  public:
    LIST_ENTRY (inode_t) i_next;
    lockf_t		*i_lockf;  /* List of locks of this process. */
    lockf_t		*i_all_lf; /* Temp list of all locks for this file. */

    dev_t		 i_dev;    /* Device ID */
    ino_t		 i_ino;    /* inode number */

  private:
    HANDLE		 i_dir;
    HANDLE		 i_mtx;
    uint32_t		 i_cnt;    /* # of threads referencing this instance. */

  public:
    inode_t (dev_t dev, ino_t ino);
    ~inode_t ();

    void *operator new (size_t size)
    { return cmalloc (HEAP_FHANDLER, sizeof (inode_t)); }
    void operator delete (void *p)
    { cfree (p); }

    static inode_t *get (dev_t dev, ino_t ino,
			 bool create_if_missing, bool lock);

    void LOCK () { WaitForSingleObject (i_mtx, INFINITE); }
    void UNLOCK () { ReleaseMutex (i_mtx); }

    void use () { ++i_cnt; }
    void unuse () { if (i_cnt > 0) --i_cnt; }
    bool inuse () { return i_cnt > 0; }
    void notused () { i_cnt = 0; }

    void unlock_and_remove_if_unused ();

    lockf_t *get_all_locks_list ();

    bool del_my_locks (long long id, HANDLE fhdl);
};

inode_t::~inode_t ()
{
  lockf_t *lock, *n_lock;
  for (lock = i_lockf; lock && (n_lock = lock->lf_next, 1); lock = n_lock)
    delete lock;
  NtClose (i_mtx);
  NtClose (i_dir);
}

void
inode_t::unlock_and_remove_if_unused ()
{
  UNLOCK ();
  INODE_LIST_LOCK ();
  unuse ();
  if (i_lockf == NULL && !inuse ())
    {
      LIST_REMOVE (this, i_next);
      delete this;
    }
  INODE_LIST_UNLOCK ();
}

bool
inode_t::del_my_locks (long long id, HANDLE fhdl)
{
  lockf_t *lock, *n_lock;
  lockf_t **prev = &i_lockf;
  for (lock = *prev; lock && (n_lock = lock->lf_next, 1); lock = n_lock)
    {
      if (lock->lf_flags & F_POSIX)
	{
	  /* Delete all POSIX locks. */
	  *prev = n_lock;
	  /* When called during fork, the POSIX lock must get deleted but
	     *not* signalled.  The lock is still active and locked in the
	     parent.  So in case of fork, we call close_lock_obj explicitely,
	     since del_lock_obj is called from the destructor. */
	  if (!id)
	    lock->close_lock_obj ();
	  delete lock;
	}
      else if (id && lock->lf_id == id)
	{
	  int cnt = 0;
	  cygheap_fdenum cfd (true);
	  while (cfd.next () >= 0)
	    if (cfd->get_unique_id () == lock->lf_id && ++cnt > 1)
	      break;
	  /* Delete BSD flock lock when no other fd in this process references
	     it anymore. */
	  if (cnt <= 1)
	    {
	      *prev = n_lock;
	      lock->del_lock_obj (fhdl);
	      delete lock;
	    }
	}
      else
	prev = &lock->lf_next;
    }
  return i_lockf == NULL;
}

/* Used to delete the locks on a file hold by this process.  Called from
   close(2) and fixup_after_fork, as well as from fixup_after_exec in
   case the close_on_exec flag is set.  The whole inode is deleted as
   soon as no lock exists on it anymore. */
void
fhandler_base::del_my_locks (del_lock_called_from from)
{
  inode_t *node = inode_t::get (get_dev (), get_ino (), false, true);
  if (node)
    {
      /* When we're called from fixup_after_exec, the fhandler is a
	 close-on-exec fhandler.  In this case our io handle is already
	 invalid.  We can't use it to test for the object reference count.
	 However, that shouldn't be necessary for the following reason.
	 After exec, there are no threads in the current process waiting for
	 the lock.  So, either we're the only process accessing the file table
	 entry and there are no threads which require signalling, or we have
	 a parent process still accessing the file object and signalling the
	 lock event would be premature. */
      node->del_my_locks (from == after_fork ? 0 : get_unique_id (),
			  from == after_exec ? NULL : get_handle ());
      node->unlock_and_remove_if_unused ();
    }
}

/* Called in an execed child.  The exec'ed process must allow SYNCHRONIZE
   access to everyone if at least one inode exists.
   The lock owner's Windows PID changed and all POSIX lock event objects
   have to be relabeled so that waiting processes know which process to
   wait on.  If the node has been abandoned due to close_on_exec on the
   referencing fhandlers, remove the inode entirely. */
void
fixup_lockf_after_exec (bool exec)
{
  inode_t *node, *next_node;

  INODE_LIST_LOCK ();
  if (LIST_FIRST (&cygheap->inode_list))
    allow_others_to_sync ();
  LIST_FOREACH_SAFE (node, &cygheap->inode_list, i_next, next_node)
    {
      node->notused ();
      int cnt = 0;
      cygheap_fdenum cfd (true);
      while (cfd.next () >= 0)
	if (cfd->get_dev () == node->i_dev
	    && cfd->get_ino () == node->i_ino
	    && ++cnt >= 1)
	  break;
      if (cnt == 0)
	{
	  LIST_REMOVE (node, i_next);
	  delete node;
	}
      else
	{
	  node->LOCK ();
	  lockf_t *lock, *n_lock;
	  lockf_t **prev = &node->i_lockf;
	  for (lock = *prev; lock && (n_lock = lock->lf_next, 1); lock = n_lock)
	    if (lock->lf_flags & F_POSIX)
	      {
		if (exec)
		  {
		    /* The parent called exec.  The lock is passed to the child.
		       Recreate lock object with changed ownership. */
		    lock->del_lock_obj (NULL);
		    lock->lf_wid = myself->dwProcessId;
		    lock->lf_ver = 0;
		    lock->create_lock_obj ();
		  }
		else
		  {
		    /* The parent called spawn.  The parent continues to hold
		       the POSIX lock, ownership is not passed to the child.
		       Give up the lock in the child. */
		    *prev = n_lock;
		    lock->close_lock_obj ();
		    delete lock;
		  }
	      }
	  node->UNLOCK ();
	}
    }
  INODE_LIST_UNLOCK ();
}

/* static method to return a pointer to the inode_t structure for a specific
   file.  The file is specified by the device and inode_t number.  If inode_t
   doesn't exist, create it. */
inode_t *
inode_t::get (dev_t dev, ino_t ino, bool create_if_missing, bool lock)
{
  inode_t *node;

  INODE_LIST_LOCK ();
  LIST_FOREACH (node, &cygheap->inode_list, i_next)
    if (node->i_dev == dev && node->i_ino == ino)
      break;
  if (!node && create_if_missing)
    {
      node = new inode_t (dev, ino);
      if (node)
	LIST_INSERT_HEAD (&cygheap->inode_list, node, i_next);
    }
  if (node)
    node->use ();
  INODE_LIST_UNLOCK ();
  if (node && lock)
    node->LOCK ();
  return node;
}

inode_t::inode_t (dev_t dev, ino_t ino)
: i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino), i_cnt (0L)
{
  HANDLE parent_dir;
  WCHAR name[48];
  UNICODE_STRING uname;
  OBJECT_ATTRIBUTES attr;
  NTSTATUS status;

  parent_dir = get_shared_parent_dir ();
  /* Create a subdir which is named after the device and inode_t numbers
     of the given file, in hex notation. */
  int len = __small_swprintf (name, LOCK_DIR_NAME_FMT, dev, ino);
  RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR));
  InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
			      parent_dir, everyone_sd (FLOCK_INODE_DIR_ACCESS));
  status = NtCreateDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
  if (!NT_SUCCESS (status))
    api_fatal ("NtCreateDirectoryObject(inode): %y", status);
  /* Create a mutex object in the file specific dir, which is used for
     access synchronization on the dir and its objects. */
  InitializeObjectAttributes (&attr, &ro_u_mtx, OBJ_INHERIT | OBJ_OPENIF, i_dir,
			      everyone_sd (CYG_MUTANT_ACCESS));
  status = NtCreateMutant (&i_mtx, CYG_MUTANT_ACCESS, &attr, FALSE);
  if (!NT_SUCCESS (status))
    api_fatal ("NtCreateMutant(inode): %y", status);
}

/* Enumerate all lock event objects for this file and create a lockf_t
   list in the i_all_lf member.  This list is searched in lf_getblock
   for locks which potentially block our lock request. */

/* Number of lockf_t structs which fit in the temporary buffer. */
#define MAX_LOCKF_CNT	((intptr_t)((NT_MAX_PATH * sizeof (WCHAR)) \
				    / sizeof (lockf_t)))

bool
lockf_t::from_obj_name (inode_t *node, lockf_t **head, const wchar_t *name)
{
  wchar_t *endptr;

  /* "%02x-%01x-%016X-%016X-%016X-%08x-%04x",
     lf_flags, lf_type, lf_start, lf_end, lf_id, lf_wid, lf_ver */
  lf_flags = wcstol (name, &endptr, 16);
  if ((lf_flags & ~(F_FLOCK | F_POSIX)) != 0
      || ((lf_flags & (F_FLOCK | F_POSIX)) == (F_FLOCK | F_POSIX)))
    return false;
  lf_type = wcstol (endptr + 1, &endptr, 16);
  if ((lf_type != F_RDLCK && lf_type != F_WRLCK) || !endptr || *endptr != L'-')
    return false;
  lf_start = (off_t) wcstoull (endptr + 1, &endptr, 16);
  if (lf_start < 0 || !endptr || *endptr != L'-')
    return false;
  lf_end = (off_t) wcstoull (endptr + 1, &endptr, 16);
  if (lf_end < -1LL
      || (lf_end > 0 && lf_end < lf_start)
      || !endptr || *endptr != L'-')
    return false;
  lf_id = wcstoll (endptr + 1, &endptr, 16);
  if (!endptr || *endptr != L'-'
      || ((lf_flags & F_POSIX) && (lf_id < 1 || lf_id > UINT32_MAX)))
    return false;
  lf_wid = wcstoul (endptr + 1, &endptr, 16);
  if (!endptr || *endptr != L'-')
    return false;
  lf_ver = wcstoul (endptr + 1, &endptr, 16);
  if (endptr && *endptr != L'\0')
    return false;
  lf_head = head;
  lf_inode = node;
  lf_next = NULL;
  lf_obj = NULL;
  return true;
}

lockf_t *
inode_t::get_all_locks_list ()
{
  struct fdbi
  {
    DIRECTORY_BASIC_INFORMATION dbi;
    WCHAR buf[2][NAME_MAX + 1];
  } f;
  ULONG context;
  NTSTATUS status;
  lockf_t newlock, *lock = i_all_lf;

  for (BOOLEAN restart = TRUE;
       NT_SUCCESS (status = NtQueryDirectoryObject (i_dir, &f, sizeof f, TRUE,
						    restart, &context, NULL));
       restart = FALSE)
    {
      if (f.dbi.ObjectName.Length != LOCK_OBJ_NAME_LEN * sizeof (WCHAR))
	continue;
      f.dbi.ObjectName.Buffer[LOCK_OBJ_NAME_LEN] = L'\0';
      if (!newlock.from_obj_name (this, &i_all_lf, f.dbi.ObjectName.Buffer))
	continue;
      if (lock - i_all_lf >= MAX_LOCKF_CNT)
	{
	  system_printf ("Warning, can't handle more than %d locks per file.",
			 MAX_LOCKF_CNT);
	  break;
	}
      if (lock > i_all_lf)
	lock[-1].lf_next = lock;
      new (lock++) lockf_t (newlock);
    }
  /* If no lock has been found, return NULL. */
  if (lock == i_all_lf)
    return NULL;
  return i_all_lf;
}

/* Create the lock object name.  The name is constructed from the lock
   properties which identify it uniquely, all values in hex. */
POBJECT_ATTRIBUTES
lockf_t::create_lock_obj_attr (lockfattr_t *attr, ULONG flags, void *sd_buf)
{
  __small_swprintf (attr->name, LOCK_OBJ_NAME_FMT,
		    lf_flags & (F_POSIX | F_FLOCK), lf_type, lf_start, lf_end,
		    lf_id, lf_wid, lf_ver);
  RtlInitCountedUnicodeString (&attr->uname, attr->name,
			       LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
  InitializeObjectAttributes (&attr->attr, &attr->uname, flags, lf_inode->i_dir,
			      _everyone_sd (sd_buf, FLOCK_EVENT_ACCESS));
  return &attr->attr;
}

DWORD WINAPI
create_lock_in_parent (PVOID param)
{
  HANDLE lf_obj;
  ULONG size;
  OBJECT_NAME_INFORMATION *ntfn;
  NTSTATUS status;
  wchar_t *lockname, *inodename, *endptr;
  dev_t dev;
  ino_t ino;
  inode_t *node;
  lockf_t newlock, *lock;
  int cnt;

  /* param is the handle to the lock object, created by caller. */
  lf_obj = (HANDLE) param;
  /* Fetch object path from handle.  Typically the length of the path
     is 146 characters, starting with
     "\BaseNamedObject\cygwin-1S5-<16-hex-digits>\..." */
  size = sizeof (OBJECT_NAME_INFORMATION) + 256 * sizeof (WCHAR);
  ntfn = (OBJECT_NAME_INFORMATION *) alloca (size);
  memset (ntfn, 0, size);
  status = NtQueryObject (lf_obj, ObjectNameInformation, ntfn, size, &size);
  if (!NT_SUCCESS (status))
    goto err;
  ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = L'\0';
  /* Sanity check so that we don't peek into unchartered territory. */
  if (ntfn->Name.Length < LOCK_OBJ_NAME_LEN + LOCK_DIR_NAME_LEN + 1)
    goto err;
  /* The names have fixed size, so we know where the substrings start. */
  lockname = ntfn->Name.Buffer + ntfn->Name.Length / sizeof (WCHAR)
			       - LOCK_OBJ_NAME_LEN;
  inodename = lockname - LOCK_DIR_NAME_LEN - 1;
  dev = wcstoul (inodename + LOCK_DIR_NAME_DEV_OFF, &endptr, 16);
  if (*endptr != L'-')
    goto err;
  ino = wcstoull (inodename + LOCK_DIR_NAME_INO_OFF, &endptr, 16);
  if (*endptr != L'\\')
    goto err;
  if (!newlock.from_obj_name (NULL, NULL, lockname))
    goto err;
  /* Check if we have an open file handle with the same unique id. */
  {
    cnt = 0;
    cygheap_fdenum cfd (true);
    while (cfd.next () >= 0)
      if (cfd->get_unique_id () == newlock.lf_id && ++cnt > 0)
	break;
  }
  /* If not, close handle and return. */
  if (!cnt)
    {
      NtClose (lf_obj);
      return 0;
    }
  /* The handle gets created non-inheritable.  That's fine, unless the parent
     starts another process accessing this object.  So, after it's clear we
     have to store the handle for further use, make sure it gets inheritable
     by child processes. */
  if (!SetHandleInformation (lf_obj, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
    goto err;
  /* otherwise generate inode from directory name... */
  node = inode_t::get (dev, ino, true, false);
  /* ...and generate lock from object name. */
  lock = new lockf_t (newlock);
  lock->lf_inode = node;
  lock->lf_head = &node->i_lockf;
  lock->lf_next = node->i_lockf;
  lock->lf_obj = lf_obj;
  node->i_lockf = lock;
  node->unuse ();
  return 0;

err:
  system_printf ("Adding <%S> lock failed", &ntfn->Name);
  NtClose (lf_obj);
  return 1;
}

DWORD WINAPI
delete_lock_in_parent (PVOID param)
{
  inode_t *node, *next_node;
  lockf_t *lock, **prev;

  /* Scan list of all inodes, and reap stale BSD lock if lf_id matches.
     Remove inode if empty. */
  INODE_LIST_LOCK ();
  LIST_FOREACH_SAFE (node, &cygheap->inode_list, i_next, next_node)
    if (!node->inuse ())
      {
	for (prev = &node->i_lockf, lock = *prev; lock; lock = *prev)
	  {
	    if ((lock->lf_flags & F_FLOCK) && IsEventSignalled (lock->lf_obj))
	      {
		*prev = lock->lf_next;
		delete lock;
	      }
	    else
	      prev = &lock->lf_next;
	  }
	if (node->i_lockf == NULL)
	  {
	    LIST_REMOVE (node, i_next);
	    delete node;
	  }
      }
  INODE_LIST_UNLOCK ();
  return 0;
}

/* Create the lock event object in the file's subdir in the NT global
   namespace. */
void
lockf_t::create_lock_obj ()
{
  lockfattr_t attr;
  NTSTATUS status;
  PSECURITY_DESCRIPTOR sd_buf = alloca (SD_MIN_SIZE);
  POBJECT_ATTRIBUTES lock_obj_attr;

  do
    {
      lock_obj_attr = create_lock_obj_attr (&attr, OBJ_INHERIT, sd_buf);
      status = NtCreateEvent (&lf_obj, CYG_EVENT_ACCESS, lock_obj_attr,
			      NotificationEvent, FALSE);
      if (!NT_SUCCESS (status))
	{
	  if (status != STATUS_OBJECT_NAME_COLLISION)
	    api_fatal ("NtCreateEvent(lock): %y", status);
	  /* If we get a STATUS_OBJECT_NAME_COLLISION, the event still exists
	     because some other process is waiting for it in lf_setlock.
	     If so, check the event's signal state.  If we can't open it, it
	     has been closed in the meantime, so just try again.  If we can
	     open it and the object is not signalled, it's surely a bug in the
	     code somewhere.  Otherwise, close the event and retry to create
	     a new event with another name. */
	  if (open_lock_obj ())
	    {
	      if (!IsEventSignalled (lf_obj))
		api_fatal ("NtCreateEvent(lock): %y", status);
	      close_lock_obj ();
	      /* Increment the lf_ver field until we have no collision. */
	      ++lf_ver;
	    }
	}
    }
  while (!NT_SUCCESS (status));
  /* For BSD locks, notify the parent process. */
  if (lf_flags & F_FLOCK)
    {
      HANDLE parent_proc, parent_thread, parent_lf_obj;

      pinfo p (myself->ppid);
      if (!p)	/* No access or not a Cygwin parent. */
      	return;

      parent_proc = OpenProcess (PROCESS_DUP_HANDLE
				 | PROCESS_CREATE_THREAD
				 | PROCESS_QUERY_INFORMATION
				 | PROCESS_VM_OPERATION
				 | PROCESS_VM_WRITE
				 | PROCESS_VM_READ,
				 FALSE, p->dwProcessId);
      if (!parent_proc)
	{
	  debug_printf ("OpenProcess (%u): %E", p->dwProcessId);
	  return;
	}
      if (!DuplicateHandle (GetCurrentProcess (), lf_obj, parent_proc,
			    &parent_lf_obj, TRUE, FALSE, DUPLICATE_SAME_ACCESS))
	debug_printf ("DuplicateHandle (lf_obj): %E");
      else
	{
	  parent_thread = CreateRemoteThread (parent_proc, NULL, 256 * 1024,
					      create_lock_in_parent,
					      parent_lf_obj,
					      STACK_SIZE_PARAM_IS_A_RESERVATION,
					      NULL);
	  if (!parent_thread)
	    {
	      debug_printf ("CreateRemoteThread: %E");
	      /* If thread didn't get started, close object handle in parent,
		 otherwise suffer handle leaks. */
	      DuplicateHandle (parent_proc, parent_lf_obj, parent_proc,
			       NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
	    }
	  else
	    {
	      /* Must wait to avoid race conditions. */
	      WaitForSingleObject (parent_thread, INFINITE);
	      CloseHandle (parent_thread);
	    }
	}
      CloseHandle (parent_proc);
    }
}

/* Open a lock event object for SYNCHRONIZE access (to wait for it). */
bool
lockf_t::open_lock_obj ()
{
  lockfattr_t attr;
  NTSTATUS status;

  status = NtOpenEvent (&lf_obj, FLOCK_EVENT_ACCESS,
			create_lock_obj_attr (&attr, 0, alloca (SD_MIN_SIZE)));
  if (!NT_SUCCESS (status))
    {
      SetLastError (RtlNtStatusToDosError (status));
      lf_obj = NULL; /* Paranoia... */
    }
  return lf_obj != NULL;
}

/* Delete a lock event handle.  The important thing here is to signal it
   before closing the handle.  This way all threads waiting for this lock
   can wake up. */
void
lockf_t::del_lock_obj (HANDLE fhdl, bool signal)
{
  if (lf_obj)
    {
      /* Only signal the event if it's either a POSIX lock, or, in case of
	 BSD flock locks, if it's an explicit unlock or if the calling fhandler
	 holds the last reference to the file table entry.  The file table
	 entry in UNIX terms is equivalent to the FILE_OBJECT in Windows NT
	 terms.  It's what the handle/descriptor references when calling
	 CreateFile/open.  Calling DuplicateHandle/dup only creates a new
	 handle/descriptor to the same FILE_OBJECT/file table entry. */
      if ((lf_flags & F_POSIX) || signal
	  || (fhdl && get_obj_handle_count (fhdl) <= 1))
	{
	  NTSTATUS status = NtSetEvent (lf_obj, NULL);
	  if (!NT_SUCCESS (status))
	    system_printf ("NtSetEvent, %y", status);
	  /* For BSD locks, notify the parent process. */
	  if (lf_flags & F_FLOCK)
	    {
	      HANDLE parent_proc, parent_thread;

	      pinfo p (myself->ppid);
	      if (p && (parent_proc = OpenProcess (PROCESS_CREATE_THREAD
					     | PROCESS_QUERY_INFORMATION
					     | PROCESS_VM_OPERATION
					     | PROCESS_VM_WRITE
					     | PROCESS_VM_READ,
					     FALSE, p->dwProcessId)))
		{
		  parent_thread = CreateRemoteThread (parent_proc, NULL,
					      256 * 1024, delete_lock_in_parent,
					      NULL,
					      STACK_SIZE_PARAM_IS_A_RESERVATION,
					      NULL);
		  if (parent_thread)
		    {
		      /* Must wait to avoid race conditions. */
		      WaitForSingleObject (parent_thread, INFINITE);
		      CloseHandle (parent_thread);
		    }
		  CloseHandle (parent_proc);
		}
	    }
	}
      close_lock_obj ();
    }
}

lockf_t::~lockf_t ()
{
  del_lock_obj (NULL);
}

/*
 * This variable controls the maximum number of processes that will
 * be checked in doing deadlock detection.
 */
#ifndef __CYGWIN__
#define MAXDEPTH 50
static int maxlockdepth = MAXDEPTH;
#endif

#define NOLOCKF (struct lockf_t *)0
#define SELF    0x1
#define OTHERS  0x2
static int      lf_clearlock (lockf_t *, lockf_t **, HANDLE);
static int      lf_findoverlap (lockf_t *, lockf_t *, int, lockf_t ***, lockf_t **);
static lockf_t *lf_getblock (lockf_t *, inode_t *node);
static int      lf_getlock (lockf_t *, inode_t *, struct flock *);
static int      lf_setlock (lockf_t *, inode_t *, lockf_t **, HANDLE);
static void     lf_split (lockf_t *, lockf_t *, lockf_t **);
static void     lf_wakelock (lockf_t *, HANDLE);

/* This is the fcntl advisory lock implementation.  For the implementation
   of mandatory locks using the Windows mandatory locking functions, see the
   fhandler_disk_file::mand_lock method at the end of this file. */
int
fhandler_base::lock (int a_op, struct flock *fl)
{
  off_t start, end, oadd;
  int error = 0;

  short a_flags = fl->l_type & (F_POSIX | F_FLOCK);
  short type = fl->l_type & (F_RDLCK | F_WRLCK | F_UNLCK);

  if (!a_flags)
    a_flags = F_POSIX; /* default */

  /* FIXME: For BSD flock(2) we need a valid, per file table entry OS handle.
     Therefore we can't allow using flock(2) on nohandle devices and
     pre-Windows 8 console handles (recognized by their odd handle value). */
  if ((a_flags & F_FLOCK)
      && (nohandle () || (((uintptr_t) get_handle () & 0x3) == 0x3)))
    {
      set_errno (EINVAL);
      debug_printf ("BSD locking on nohandle and old-style console devices "
		    "not supported");
      return -1;
    }

  if (a_op == F_SETLKW)
    {
      a_op = F_SETLK;
      a_flags |= F_WAIT;
    }
  if (a_op == F_SETLK)
    switch (type)
      {
      case F_UNLCK:
	a_op = F_UNLCK;
	break;
      case F_RDLCK:
	/* flock semantics don't specify a requirement that the file has
	   been opened with a specific open mode, in contrast to POSIX locks
	   which require that a file is opened for reading to place a read
	   lock and opened for writing to place a write lock. */
	/* CV 2013-10-22: Test POSIX R/W mode flags rather than Windows R/W
	   access flags.  The reason is that POSIX mode flags are set for
	   all types of fhandlers, while Windows access flags are only set
	   for most of the actual Windows device backed fhandlers. */
	if ((a_flags & F_POSIX)
	    && ((get_flags () & O_ACCMODE) == O_WRONLY))
	  {
	    debug_printf ("request F_RDLCK on O_WRONLY file: EBADF");
	    set_errno (EBADF);
	    return -1;
	  }
	break;
      case F_WRLCK:
	/* See above comment. */
	if ((a_flags & F_POSIX)
	    && ((get_flags () & O_ACCMODE) == O_RDONLY))
	  {
	    debug_printf ("request F_WRLCK on O_RDONLY file: EBADF");
	    set_errno (EBADF);
	    return -1;
	  }
	break;
      default:
	set_errno (EINVAL);
	return -1;
      }

  /*
   * Convert the flock structure into a start and end.
   */
  switch (fl->l_whence)
    {
    case SEEK_SET:
      start = fl->l_start;
      break;

    case SEEK_CUR:
      if ((start = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK)
	start = 0;
      break;

    case SEEK_END:
      if (get_device () != FH_FS)
      	start = 0;
      else
	{
	  NTSTATUS status;
	  IO_STATUS_BLOCK io;
	  FILE_STANDARD_INFORMATION fsi;

	  status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
					   FileStandardInformation);
	  if (!NT_SUCCESS (status))
	    {
	      __seterrno_from_nt_status (status);
	      return -1;
	    }
	  if (fl->l_start > 0 && fsi.EndOfFile.QuadPart > OFF_MAX - fl->l_start)
	    {
	      set_errno (EOVERFLOW);
	      return -1;
	    }
	  start = fsi.EndOfFile.QuadPart + fl->l_start;
	}
      break;

    default:
      return (EINVAL);
    }
  if (start < 0)
    {
      set_errno (EINVAL);
      return -1;
    }
  if (fl->l_len < 0)
    {
      if (start == 0)
	{
	  set_errno (EINVAL);
	  return -1;
	}
      end = start - 1;
      start += fl->l_len;
      if (start < 0)
	{
	  set_errno (EINVAL);
	  return -1;
	}
    }
  else if (fl->l_len == 0)
    end = -1;
  else
    {
      oadd = fl->l_len - 1;
      if (oadd > OFF_MAX - start)
	{
	  set_errno (EOVERFLOW);
	  return -1;
	}
      end = start + oadd;
    }

restart:	/* Entry point after a restartable signal came in. */

  inode_t *node = inode_t::get (get_dev (), get_ino (), true, true);
  if (!node)
    {
      set_errno (ENOLCK);
      return -1;
    }

  /* Unlock the fd table which has been locked in fcntl_worker/lock_worker,
     otherwise a blocking F_SETLKW never wakes up on a signal. */
  cygheap->fdtab.unlock ();

  lockf_t **head = &node->i_lockf;

#if 0
  /*
   * Avoid the common case of unlocking when inode_t has no locks.
   *
   * This shortcut is invalid for Cygwin because the above inode_t::get
   * call returns with an empty lock list if this process has no locks
   * on the file yet.
   */
  if (*head == NULL)
    {
      if (a_op != F_SETLK)
	{
	  node->UNLOCK ();
	  fl->l_type = F_UNLCK;
	  return 0;
	}
    }
#endif
  /*
   * Allocate a spare structure in case we have to split.
   */
  lockf_t *clean = NULL;
  if (a_op == F_SETLK || a_op == F_UNLCK)
    {
      clean = new lockf_t ();
      if (!clean)
	{
	  node->unlock_and_remove_if_unused ();
	  set_errno (ENOLCK);
	  return -1;
	}
    }
  /*
   * Create the lockf_t structure
   */
  lockf_t *lock = new lockf_t (node, head, a_flags, type, start, end,
			       (a_flags & F_FLOCK) ? get_unique_id ()
						   : getpid (),
			       myself->dwProcessId, 0);
  if (!lock)
    {
      node->unlock_and_remove_if_unused ();
      set_errno (ENOLCK);
      return -1;
    }

  switch (a_op)
    {
    case F_SETLK:
      error = lf_setlock (lock, node, &clean, get_handle ());
      break;

    case F_UNLCK:
      error = lf_clearlock (lock, &clean, get_handle ());
      lock->lf_next = clean;
      clean = lock;
      break;

    case F_GETLK:
      error = lf_getlock (lock, node, fl);
      lock->lf_next = clean;
      clean = lock;
      break;

    default:
      lock->lf_next = clean;
      clean = lock;
      error = EINVAL;
      break;
    }
  for (lock = clean; lock != NULL; )
    {
      lockf_t *n = lock->lf_next;
      lock->del_lock_obj (get_handle (), a_op == F_UNLCK);
      delete lock;
      lock = n;
    }
  node->unlock_and_remove_if_unused ();
  switch (error)
    {
    case 0:		/* All is well. */
      need_fork_fixup (true);
      return 0;
    case EINTR:		/* Signal came in. */
      if (_my_tls.call_signal_handler ())
	goto restart;
      break;
    case ECANCELED:	/* The thread has been sent a cancellation request. */
      pthread::static_cancel_self ();
      /*NOTREACHED*/
    default:
      break;
    }
  set_errno (error);
  return -1;
}

/*
 * Set a byte-range lock.
 */
static int
lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
{
  lockf_t *block;
  lockf_t **head = lock->lf_head;
  lockf_t **prev, *overlap;
  int ovcase, priority, old_prio, needtolink;
  tmp_pathbuf tp;

  /*
   * Set the priority
   */
  priority = old_prio = GetThreadPriority (GetCurrentThread ());
  if (lock->lf_type == F_WRLCK && priority <= THREAD_PRIORITY_ABOVE_NORMAL)
    priority = THREAD_PRIORITY_HIGHEST;
  /*
   * Scan lock list for this file looking for locks that would block us.
   */
  /* Create temporary space for the all locks list. */
  node->i_all_lf = (lockf_t *) (void *) tp.w_get ();
  while ((block = lf_getblock(lock, node)))
    {
      HANDLE obj = block->lf_obj;
      block->lf_obj = NULL;

      /*
       * Free the structure and return if nonblocking.
       */
      if ((lock->lf_flags & F_WAIT) == 0)
	{
	  NtClose (obj);
	  lock->lf_next = *clean;
	  *clean = lock;
	  return EAGAIN;
	}
      /*
       * We are blocked. Since flock style locks cover
       * the whole file, there is no chance for deadlock.
       * For byte-range locks we must check for deadlock.
       *
       * Deadlock detection is done by looking through the
       * wait channels to see if there are any cycles that
       * involve us. MAXDEPTH is set just to make sure we
       * do not go off into neverland.
       */
      /* FIXME: We check the handle count of all the lock event objects
		this process holds.  If it's > 1, another process is
		waiting for one of our locks.  This method isn't overly
		intelligent.  If it turns out to be too dumb, we might
		have to remove it or to find another method. */
      if (lock->lf_flags & F_POSIX)
	for (lockf_t *lk = node->i_lockf; lk; lk = lk->lf_next)
	  if ((lk->lf_flags & F_POSIX) && get_obj_handle_count (lk->lf_obj) > 1)
	    {
	      NtClose (obj);
	      return EDEADLK;
	    }

      /*
       * For flock type locks, we must first remove
       * any shared locks that we hold before we sleep
       * waiting for an exclusive lock.
       */
      if ((lock->lf_flags & F_FLOCK) && lock->lf_type == F_WRLCK)
	{
	  lock->lf_type = F_UNLCK;
	  (void) lf_clearlock (lock, clean, fhdl);
	  lock->lf_type = F_WRLCK;
	}

      /*
       * Add our lock to the blocked list and sleep until we're free.
       * Remember who blocked us (for deadlock detection).
       */
      /* Cygwin:  No locked list.  See deadlock recognition above. */

      node->UNLOCK ();

      /* Create list of objects to wait for. */
      HANDLE w4[4] = { obj, NULL, NULL, NULL };
      DWORD wait_count = 1;

      DWORD timeout;
      HANDLE proc = NULL;
      if (lock->lf_flags & F_POSIX)
	{
	  proc = OpenProcess (SYNCHRONIZE, FALSE, block->lf_wid);
	  if (!proc)
	    timeout = 0L;
	  else
	    {
	      w4[wait_count++] = proc;
	      timeout = INFINITE;
	    }
	}
      else
	timeout = 100L;

      DWORD WAIT_SIGNAL_ARRIVED = WAIT_OBJECT_0 + wait_count;
      wait_signal_arrived here (w4[wait_count++]);

      DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
      HANDLE cancel_event = pthread::get_cancel_event ();
      if (cancel_event)
	{
	  WAIT_THREAD_CANCELED = WAIT_OBJECT_0 + wait_count;
	  w4[wait_count++] = cancel_event;
	}

      /* Wait for the blocking object and, for POSIX locks, its holding process.
	 Unfortunately, since BSD flock locks are not attached to a specific
	 process, we can't recognize an abandoned lock by sync'ing with the
	 creator process.  We have to make sure the event object is in a
	 signalled state, or that it has gone away.  The latter we can only
	 recognize by retrying to fetch the block list, so we must not wait
	 infinitely.  For POSIX locks, if the process has already exited,
	 just check if a signal or a thread cancel request arrived. */
      SetThreadPriority (GetCurrentThread (), priority);
      DWORD ret = WaitForMultipleObjects (wait_count, w4, FALSE, timeout);
      SetThreadPriority (GetCurrentThread (), old_prio);
      if (proc)
	CloseHandle (proc);
      node->LOCK ();
      /* Never close lock object handle outside of node lock! */
      NtClose (obj);
      if (ret == WAIT_SIGNAL_ARRIVED)
	{
	  /* A signal came in. */
	  lock->lf_next = *clean;
	  *clean = lock;
	  return EINTR;
	}
      else if (ret == WAIT_THREAD_CANCELED)
	{
	  /* The thread has been sent a cancellation request. */
	  lock->lf_next = *clean;
	  *clean = lock;
	  return ECANCELED;
	}
      else
	/* The lock object has been set to signalled or ...
	   for POSIX locks, the process holding the lock has exited, or ...
	   just a timeout.  Just retry. */
	continue;
    }
  allow_others_to_sync ();
  /*
   * No blocks!!  Add the lock.  Note that we will
   * downgrade or upgrade any overlapping locks this
   * process already owns.
   *
   * Handle any locks that overlap.
   */
  prev = head;
  block = *head;
  needtolink = 1;
  for (;;)
    {
      ovcase = lf_findoverlap (block, lock, SELF, &prev, &overlap);
      if (ovcase)
	block = overlap->lf_next;
      /*
       * Six cases:
       *  0) no overlap
       *  1) overlap == lock
       *  2) overlap contains lock
       *  3) lock contains overlap
       *  4) overlap starts before lock
       *  5) overlap ends after lock
       */
      switch (ovcase)
	{
	case 0: /* no overlap */
	  if (needtolink)
	    {
	      *prev = lock;
	      lock->lf_next = overlap;
	      lock->create_lock_obj ();
	    }
	    break;

	case 1: /* overlap == lock */
	  /*
	   * If downgrading lock, others may be
	   * able to acquire it.
	   * Cygwin: Always wake lock.
	   */
	  lf_wakelock (overlap, fhdl);
	  overlap->lf_type = lock->lf_type;
	  overlap->create_lock_obj ();
	  lock->lf_next = *clean;
	  *clean = lock;
	  break;

	case 2: /* overlap contains lock */
	  /*
	   * Check for common starting point and different types.
	   */
	  if (overlap->lf_type == lock->lf_type)
	    {
	      lock->lf_next = *clean;
	      *clean = lock;
	      break;
	    }
	  if (overlap->lf_start == lock->lf_start)
	    {
	      *prev = lock;
	      lock->lf_next = overlap;
	      overlap->lf_start = lock->lf_end + 1;
	    }
	  else
	    lf_split (overlap, lock, clean);
	  lf_wakelock (overlap, fhdl);
	  overlap->create_lock_obj ();
	  lock->create_lock_obj ();
	  if (lock->lf_next && !lock->lf_next->lf_obj)
	    lock->lf_next->create_lock_obj ();
	  break;

	case 3: /* lock contains overlap */
	  /*
	   * If downgrading lock, others may be able to
	   * acquire it, otherwise take the list.
	   * Cygwin: Always wake old lock and create new lock.
	   */
	  lf_wakelock (overlap, fhdl);
	  /*
	   * Add the new lock if necessary and delete the overlap.
	   */
	  if (needtolink)
	    {
	      *prev = lock;
	      lock->lf_next = overlap->lf_next;
	      prev = &lock->lf_next;
	      lock->create_lock_obj ();
	      needtolink = 0;
	    }
	  else
	    *prev = overlap->lf_next;
	  overlap->lf_next = *clean;
	  *clean = overlap;
	  continue;

	case 4: /* overlap starts before lock */
	  /*
	   * Add lock after overlap on the list.
	   */
	  lock->lf_next = overlap->lf_next;
	  overlap->lf_next = lock;
	  overlap->lf_end = lock->lf_start - 1;
	  prev = &lock->lf_next;
	  lf_wakelock (overlap, fhdl);
	  overlap->create_lock_obj ();
	  lock->create_lock_obj ();
	  needtolink = 0;
	  continue;

	case 5: /* overlap ends after lock */
	  /*
	   * Add the new lock before overlap.
	   */
	  if (needtolink) {
	      *prev = lock;
	      lock->lf_next = overlap;
	  }
	  overlap->lf_start = lock->lf_end + 1;
	  lf_wakelock (overlap, fhdl);
	  lock->create_lock_obj ();
	  overlap->create_lock_obj ();
	  break;
	}
      break;
    }
  return 0;
}

/*
 * Remove a byte-range lock on an inode_t.
 *
 * Generally, find the lock (or an overlap to that lock)
 * and remove it (or shrink it), then wakeup anyone we can.
 */
static int
lf_clearlock (lockf_t *unlock, lockf_t **clean, HANDLE fhdl)
{
  lockf_t **head = unlock->lf_head;
  lockf_t *lf = *head;
  lockf_t *overlap, **prev;
  int ovcase;

  if (lf == NOLOCKF)
    return 0;
  prev = head;
  while ((ovcase = lf_findoverlap (lf, unlock, SELF, &prev, &overlap)))
    {
      /*
       * Wakeup the list of locks to be retried.
       */
      lf_wakelock (overlap, fhdl);

      switch (ovcase)
	{
	case 1: /* overlap == lock */
	  *prev = overlap->lf_next;
	  overlap->lf_next = *clean;
	  *clean = overlap;
	  break;

	case 2: /* overlap contains lock: split it */
	  if (overlap->lf_start == unlock->lf_start)
	    {
	      overlap->lf_start = unlock->lf_end + 1;
	      overlap->create_lock_obj ();
	      break;
	    }
	  lf_split (overlap, unlock, clean);
	  overlap->lf_next = unlock->lf_next;
	  overlap->create_lock_obj ();
	  if (overlap->lf_next && !overlap->lf_next->lf_obj)
	    overlap->lf_next->create_lock_obj ();
	  break;

	case 3: /* lock contains overlap */
	  *prev = overlap->lf_next;
	  lf = overlap->lf_next;
	  overlap->lf_next = *clean;
	  *clean = overlap;
	  continue;

	case 4: /* overlap starts before lock */
	    overlap->lf_end = unlock->lf_start - 1;
	    prev = &overlap->lf_next;
	    lf = overlap->lf_next;
	    overlap->create_lock_obj ();
	    continue;

	case 5: /* overlap ends after lock */
	    overlap->lf_start = unlock->lf_end + 1;
	    overlap->create_lock_obj ();
	    break;
	}
      break;
    }
  return 0;
}

/*
 * Check whether there is a blocking lock,
 * and if so return its process identifier.
 */
static int
lf_getlock (lockf_t *lock, inode_t *node, struct flock *fl)
{
  lockf_t *block;
  tmp_pathbuf tp;

  /* Create temporary space for the all locks list. */
  node->i_all_lf = (lockf_t *) (void * ) tp.w_get ();
  if ((block = lf_getblock (lock, node)))
    {
      if (block->lf_obj)
	block->close_lock_obj ();
      fl->l_type = block->lf_type;
      fl->l_whence = SEEK_SET;
      fl->l_start = block->lf_start;
      if (block->lf_end == -1)
	fl->l_len = 0;
      else
	fl->l_len = block->lf_end - block->lf_start + 1;
      if (block->lf_flags & F_POSIX)
	fl->l_pid = (pid_t) block->lf_id;
      else
	fl->l_pid = -1;
    }
  else
    fl->l_type = F_UNLCK;
  return 0;
}

/*
 * Walk the list of locks for an inode_t and
 * return the first blocking lock.
 */
static lockf_t *
lf_getblock (lockf_t *lock, inode_t *node)
{
  lockf_t **prev, *overlap;
  lockf_t *lf = node->get_all_locks_list ();
  int ovcase;

  prev = lock->lf_head;
  while ((ovcase = lf_findoverlap (lf, lock, OTHERS, &prev, &overlap)))
    {
      /*
       * We've found an overlap, see if it blocks us
       */
      if ((lock->lf_type == F_WRLCK || overlap->lf_type == F_WRLCK))
	{
	  /* Open the event object for synchronization. */
	  if (overlap->open_lock_obj ())
	    {
	      /* Check if the event object is signalled.  If so, the overlap
		 doesn't actually exist anymore.  There are just a few open
		 handles left. */
	      if (!IsEventSignalled (overlap->lf_obj))
		return overlap;
	      overlap->close_lock_obj ();
	    }
	}
      /*
       * Nope, point to the next one on the list and
       * see if it blocks us
       */
      lf = overlap->lf_next;
    }
  return NOLOCKF;
}

/*
 * Walk the list of locks for an inode_t to
 * find an overlapping lock (if any).
 *
 * NOTE: this returns only the FIRST overlapping lock.  There
 *   may be more than one.
 */
static int
lf_findoverlap (lockf_t *lf, lockf_t *lock, int type, lockf_t ***prev,
		lockf_t **overlap)
{
  off_t start, end;

  *overlap = lf;
  if (lf == NOLOCKF)
    return 0;

  start = lock->lf_start;
  end = lock->lf_end;
  while (lf != NOLOCKF)
    {
      if (((type & SELF) && lf->lf_id != lock->lf_id)
	  || ((type & OTHERS) && lf->lf_id == lock->lf_id)
	  /* As on Linux: POSIX locks and BSD flock locks don't interact. */
	  || (lf->lf_flags & (F_POSIX | F_FLOCK))
	     != (lock->lf_flags & (F_POSIX | F_FLOCK)))
	{
	  *prev = &lf->lf_next;
	  *overlap = lf = lf->lf_next;
	  continue;
	}
      /*
       * OK, check for overlap
       *
       * Six cases:
       *  0) no overlap
       *  1) overlap == lock
       *  2) overlap contains lock
       *  3) lock contains overlap
       *  4) overlap starts before lock
       *  5) overlap ends after lock
       */
      if ((lf->lf_end != -1 && start > lf->lf_end) ||
	  (end != -1 && lf->lf_start > end))
	{
	  /* Case 0 */
	  if ((type & SELF) && end != -1 && lf->lf_start > end)
	    return 0;
	  *prev = &lf->lf_next;
	  *overlap = lf = lf->lf_next;
	  continue;
	}
      if ((lf->lf_start == start) && (lf->lf_end == end))
	{
	  /* Case 1 */
	  return 1;
	}
      if ((lf->lf_start <= start) && (end != -1) &&
	  ((lf->lf_end >= end) || (lf->lf_end == -1)))
	{
	  /* Case 2 */
	  return 2;
	}
      if (start <= lf->lf_start && (end == -1 ||
	  (lf->lf_end != -1 && end >= lf->lf_end)))
	{
	  /* Case 3 */
	  return 3;
	}
      if ((lf->lf_start < start) &&
	  ((lf->lf_end >= start) || (lf->lf_end == -1)))
	{
	  /* Case 4 */
	  return 4;
	}
      if ((lf->lf_start > start) && (end != -1) &&
	  ((lf->lf_end > end) || (lf->lf_end == -1)))
	{
	  /* Case 5 */
	  return 5;
	}
      api_fatal ("lf_findoverlap: default\n");
    }
  return 0;
}

/*
 * Split a lock and a contained region into
 * two or three locks as necessary.
 */
static void
lf_split (lockf_t *lock1, lockf_t *lock2, lockf_t **split)
{
  lockf_t *splitlock;

  /*
   * Check to see if spliting into only two pieces.
   */
  if (lock1->lf_start == lock2->lf_start)
    {
      lock1->lf_start = lock2->lf_end + 1;
      lock2->lf_next = lock1;
      return;
    }
  if (lock1->lf_end == lock2->lf_end)
    {
      lock1->lf_end = lock2->lf_start - 1;
      lock2->lf_next = lock1->lf_next;
      lock1->lf_next = lock2;
      return;
    }
  /*
   * Make a new lock consisting of the last part of
   * the encompassing lock.  We use the preallocated
   * splitlock so we don't have to block.
   */
  splitlock = *split;
  assert (splitlock != NULL);
  *split = splitlock->lf_next;
  memcpy (splitlock, lock1, sizeof *splitlock);
  /* We have to unset the obj HANDLE here which has been copied by the
     above memcpy, so that the calling function recognizes the new object.
     See post-lf_split handling in lf_setlock and lf_clearlock. */
  splitlock->lf_obj = NULL;
  splitlock->lf_start = lock2->lf_end + 1;
  lock1->lf_end = lock2->lf_start - 1;
  /*
   * OK, now link it in
   */
  splitlock->lf_next = lock1->lf_next;
  lock2->lf_next = splitlock;
  lock1->lf_next = lock2;
}

/*
 * Wakeup a blocklist
 * Cygwin: Just signal the lock which gets removed.  This unblocks
 * all threads waiting for this lock.
 */
static void
lf_wakelock (lockf_t *listhead, HANDLE fhdl)
{
  listhead->del_lock_obj (fhdl, true);
}

extern "C" int
flock (int fd, int operation)
{
  int res = -1;
  int cmd;
  struct flock fl = { 0, SEEK_SET, 0, 0, 0 };

  __try
    {
      cygheap_fdget cfd (fd);
      if (cfd < 0)
	__leave;

      cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
      switch (operation & (~LOCK_NB))
	{
	case LOCK_EX:
	  fl.l_type = F_WRLCK;
	  break;
	case LOCK_SH:
	  fl.l_type = F_RDLCK;
	  break;
	case LOCK_UN:
	  fl.l_type = F_UNLCK;
	  break;
	default:
	  set_errno (EINVAL);
	  __leave;
	}
      if (!cfd->mandatory_locking ())
	fl.l_type |= F_FLOCK;
      res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
				      : cfd->lock (cmd, &fl);
      if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
	set_errno (EWOULDBLOCK);
    }
  __except (EFAULT) {}
  __endtry
  syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
  return res;
}

extern "C" int
lockf (int filedes, int function, off_t size)
{
  int res = -1;
  int cmd;
  struct flock fl;

  pthread_testcancel ();

  __try
    {
      cygheap_fdget cfd (filedes);
      if (cfd < 0)
	__leave;

      fl.l_start = 0;
      fl.l_len = size;
      fl.l_whence = SEEK_CUR;

      switch (function)
	{
	case F_ULOCK:
	  cmd = F_SETLK;
	  fl.l_type = F_UNLCK;
	  break;
	case F_LOCK:
	  cmd = F_SETLKW;
	  fl.l_type = F_WRLCK;
	  break;
	case F_TLOCK:
	  cmd = F_SETLK;
	  fl.l_type = F_WRLCK;
	  break;
	case F_TEST:
	  fl.l_type = F_WRLCK;
	  if (cfd->lock (F_GETLK, &fl) == -1)
	    __leave;
	  if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
	    res = 0;
	  else
	    errno = EAGAIN;
	  __leave;
	  /* NOTREACHED */
	default:
	  errno = EINVAL;
	  __leave;
	  /* NOTREACHED */
	}
      res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
				      : cfd->lock (cmd, &fl);
    }
  __except (EFAULT) {}
  __endtry
  syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
  return res;
}

/* This is the fcntl lock implementation for mandatory locks using the
   Windows mandatory locking functions.  For the UNIX-like advisory locking
   implementation see the fhandler_disk_file::lock method earlier in this
   file. */
struct lock_parms {
  HANDLE	   h;
  PIO_STATUS_BLOCK pio;
  PLARGE_INTEGER   poff;
  PLARGE_INTEGER   plen;
  BOOL		   type;
  NTSTATUS	   status;
};

static DWORD WINAPI
blocking_lock_thr (LPVOID param)
{
  struct lock_parms *lp = (struct lock_parms *) param;
  lp->status = NtLockFile (lp->h, NULL, NULL, NULL, lp->pio, lp->poff,
			   lp->plen, 0, FALSE, lp->type);
  return 0;
}

int
fhandler_base::mand_lock (int, struct flock *)
{
  set_errno (EINVAL);
  return -1;
}

int
fhandler_disk_file::mand_lock (int a_op, struct flock *fl)
{
  NTSTATUS status;
  IO_STATUS_BLOCK io;
  FILE_POSITION_INFORMATION fpi;
  FILE_STANDARD_INFORMATION fsi;
  off_t startpos;
  LARGE_INTEGER offset;
  LARGE_INTEGER length;

  /* Calculate where to start from, then adjust this by fl->l_start. */
  switch (fl->l_whence)
  {
    case SEEK_SET:
      startpos = 0;
      break;
    case SEEK_CUR:
      status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
				       FilePositionInformation);
      if (!NT_SUCCESS (status))
	{
	  __seterrno_from_nt_status (status);
	  return -1;
	}
      startpos = fpi.CurrentByteOffset.QuadPart;
      break;
    case SEEK_END:
      status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
				       FileStandardInformation);
      if (!NT_SUCCESS (status))
	{
	  __seterrno_from_nt_status (status);
	  return -1;
	}
      startpos = fsi.EndOfFile.QuadPart;
      break;
    default:
      set_errno (EINVAL);
      return -1;
  }
  /* Adjust start and length until they make sense. */
  offset.QuadPart = startpos + fl->l_start;
  if (fl->l_len < 0)
    {
      offset.QuadPart -= fl->l_len;
      length.QuadPart = -fl->l_len;
    }
  else
    length.QuadPart = fl->l_len;
  if (offset.QuadPart < 0)
    {
      length.QuadPart -= -offset.QuadPart;
      if (length.QuadPart <= 0)
        {
          set_errno (EINVAL);
          return -1;
        }
      offset.QuadPart = 0;
    }
  /* Special case if len == 0.  For POSIX this means lock to the end of
     the entire file, even when file grows later. */
  if (length.QuadPart == 0)
    length.QuadPart = UINT64_MAX;
  /* Action! */
  if (fl->l_type == F_UNLCK)
    {
      status = NtUnlockFile (get_handle (), &io, &offset, &length, 0);
      if (status == STATUS_RANGE_NOT_LOCKED)	/* Not an error */
	status = STATUS_SUCCESS;
    }
  else if (a_op == F_SETLKW)
    {
      /* We open file handles synchronously.  To allow asynchronous operation
	 the file locking functions require a file handle opened in asynchronous
	 mode.  Since Windows locks are per-process/per-file object, we can't
	 open another handle asynchrously and lock/unlock using that handle:
	 The original file handle would not have placed the lock and would be
	 restricted by the lock like any other file handle.
	 So, what we do here is to start a thread which calls the potentially
	 blocking NtLockFile call.  Then we wait for thread completion in an
	 interruptible fashion. */
      OBJECT_ATTRIBUTES attr;
      HANDLE evt;
      struct lock_parms lp = { get_handle (), &io, &offset, &length,
			       fl->l_type == F_WRLCK, 0 };
      cygthread *thr = NULL;

      InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL);
      status = NtCreateEvent (&evt, EVENT_ALL_ACCESS, &attr,
			      NotificationEvent, FALSE);
      if (evt)
	thr = new cygthread (blocking_lock_thr, &lp, "blk_lock", evt);
      if (!thr)
	{
	  /* Thread creation failed.  Fall back to blocking lock call. */
	  if (evt)
	    NtClose (evt);
	  status = NtLockFile (get_handle (), NULL, NULL, NULL, &io, &offset,
			       &length, 0, FALSE, fl->l_type == F_WRLCK);
	}
      else
	{
	  /* F_SETLKW and lock cannot be established.  Wait until the lock can
	     be established, or a signal request arrived.  We deliberately
	     don't handle thread cancel requests here. */
	  DWORD wait_res = cygwait (evt, INFINITE, cw_sig | cw_sig_eintr);
	  NtClose (evt);
	  switch (wait_res)
	    {
	    case WAIT_OBJECT_0:
	      /* Fetch completion status. */
	      status = lp.status;
	      thr->detach ();
	      break;
	    default:
	      /* Signal arrived.
		 If CancelSynchronousIo works we wait for the thread to exit.
		 lp.status will be either STATUS_SUCCESS, or STATUS_CANCELLED.
		 We only call NtUnlockFile in the first case.
		 If CancelSynchronousIo fails we terminated the thread and
		 call NtUnlockFile since lp.status was 0 to begin with. */
	      if (CancelSynchronousIo (thr->thread_handle ()))
		thr->detach ();
	      else
	      	thr->terminate_thread ();
	      if (NT_SUCCESS (lp.status))
		NtUnlockFile (get_handle (), &io, &offset, &length, 0);
	      /* Per SUSv4: If a signal is received while fcntl is waiting,
		 fcntl shall be interrupted.  Upon return from the signal
		 handler, fcntl shall return -1 with errno set to EINTR,
		 and the lock operation shall not be done. */
	      _my_tls.call_signal_handler ();
	      set_errno (EINTR);
	      return -1;
	    }
	}
    }
  else
    {
      status = NtLockFile (get_handle (), NULL, NULL, NULL, &io, &offset,
			   &length, 0, TRUE, fl->l_type == F_WRLCK);
      if (a_op == F_GETLK)
	{
	  /* This is non-atomic, but there's no other way on Windows to detect
	     if another lock is blocking our lock, other than trying to place
	     the lock, and then having to unlock it again. */
	  if (NT_SUCCESS (status))
	    {
	      NtUnlockFile (get_handle (), &io, &offset, &length, 0);
	      fl->l_type = F_UNLCK;
	    }
	  else
	    {
	      /* FAKE! FAKE! FAKE! */
	      fl->l_type = F_WRLCK;
	      fl->l_whence = SEEK_SET;
	      fl->l_start = offset.QuadPart;
	      fl->l_len = length.QuadPart;
	      fl->l_pid = (pid_t) -1;
	    }
	  status = STATUS_SUCCESS;
	}
    }
  if (!NT_SUCCESS (status))
    {
      __seterrno_from_nt_status (status);
      return -1;
    }
  return 0;
}
