summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler.cc')
-rw-r--r--winsup/cygwin/fhandler.cc19
1 files changed, 19 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 2c41f31ae..6e4539c72 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -498,6 +498,12 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
}
close_on_exec (flags & O_CLOEXEC);
+ /* A unique ID is necessary to recognize fhandler entries which are
+ duplicated by dup(2) or fork(2). This is used in BSD flock calls
+ to identify the descriptor. Skip nohandle fhandlers since advisory
+ locking is unusable for those anyway. */
+ if (!nohandle ())
+ set_unique_id ();
return res;
}
@@ -1112,6 +1118,10 @@ fhandler_base::close_with_arch ()
void
fhandler_base::cleanup ()
{
+ /* Delete all POSIX locks on the file. Delete all flock locks on the
+ file if this is the last reference to this file. */
+ if (unique_id)
+ del_my_locks (on_close);
}
int
@@ -1366,6 +1376,15 @@ int fhandler_base::fcntl (int cmd, intptr_t arg)
}
res = 0;
break;
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ {
+ struct flock *fl = (struct flock *) arg;
+ fl->l_type &= F_RDLCK | F_WRLCK | F_UNLCK;
+ res = mandatory_locking () ? mand_lock (cmd, fl) : lock (cmd, fl);
+ }
+ break;
default:
set_errno (EINVAL);
res = -1;