From edd73646f3c33f22d90957f1675308f902c6a00e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 4 Jun 2013 10:24:43 +0000 Subject: [PATCH] * fhandler.cc (fhandler_base::lock): Move to flock.cc. (fhandler_base::fixup_after_exec): Reset mandatory_locking. * fhandler.h (class fhandler_base): Add mandatory_locking status flag. Add mandatory_locking accessor methods. Accommodate change throughout. (fhandler_base::mand_lock): Declare. (class fhandler_disk_file): Drop in favor of new status flag. * (fhandler_disk_file::fcntl): Call need_fork_fixup if mandatory_locking flag gets set. * flock.cc (fhandler_base::lock): Define here. (flock): Handle mandatory_locking. (lockf): Ditto. (fhandler_base::mand_lock): Define. --- winsup/cygwin/ChangeLog | 15 +++++++++++++++ winsup/cygwin/fhandler.cc | 8 +------- winsup/cygwin/fhandler.h | 6 ++++-- winsup/cygwin/fhandler_disk_file.cc | 12 ++++++------ winsup/cygwin/flock.cc | 28 +++++++++++++++++++++++----- winsup/cygwin/release/1.7.19 | 4 ++-- 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6a41485e1..379c97cd9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2013-06-04 Corinna Vinschen + + * fhandler.cc (fhandler_base::lock): Move to flock.cc. + (fhandler_base::fixup_after_exec): Reset mandatory_locking. + * fhandler.h (class fhandler_base): Add mandatory_locking status flag. + Add mandatory_locking accessor methods. Accommodate change throughout. + (fhandler_base::mand_lock): Declare. + (class fhandler_disk_file): Drop in favor of new status flag. + * (fhandler_disk_file::fcntl): Call need_fork_fixup if mandatory_locking + flag gets set. + * flock.cc (fhandler_base::lock): Define here. + (flock): Handle mandatory_locking. + (lockf): Ditto. + (fhandler_base::mand_lock): Define. + 2013-06-03 Corinna Vinschen * sigproc.cc (exit_thread): Allow to exit the thread while running diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index f7e3249a5..6c284a596 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1230,13 +1230,6 @@ fhandler_base::ioctl (unsigned int cmd, void *buf) return res; } -int -fhandler_base::lock (int, struct flock *) -{ - set_errno (EINVAL); - return -1; -} - int __reg2 fhandler_base::fstat (struct stat *buf) { @@ -1553,6 +1546,7 @@ fhandler_base::fixup_after_exec () debug_printf ("here for '%s'", get_name ()); if (unique_id && close_on_exec ()) del_my_locks (after_exec); + mandatory_locking (false); } void fhandler_base_overlapped::fixup_after_exec () diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 76e0ea768..f5e4bc0d6 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -147,12 +147,13 @@ class fhandler_base unsigned close_on_exec : 1; /* close-on-exec */ unsigned need_fork_fixup : 1; /* Set if need to fixup after fork. */ unsigned isclosed : 1; /* Set when fhandler is closed. */ + unsigned mandatory_locking : 1; /* Windows mandatory locking */ public: status_flags () : rbinary (0), rbinset (0), wbinary (0), wbinset (0), nohandle (0), did_lseek (0), query_open (no_query), close_on_exec (0), - need_fork_fixup (0), isclosed (0) + need_fork_fixup (0), isclosed (0), mandatory_locking (0) {} } status, open_status; @@ -247,6 +248,7 @@ class fhandler_base IMPLEMENT_STATUS_FLAG (bool, close_on_exec) IMPLEMENT_STATUS_FLAG (bool, need_fork_fixup) IMPLEMENT_STATUS_FLAG (bool, isclosed) + IMPLEMENT_STATUS_FLAG (bool, mandatory_locking) int get_default_fmode (int flags); @@ -360,6 +362,7 @@ public: virtual ssize_t __reg3 pwrite (void *, size_t, off_t); virtual off_t lseek (off_t offset, int whence); virtual int lock (int, struct flock *); + virtual int mand_lock (int, struct flock *); virtual int dup (fhandler_base *child, int flags); virtual int fpathconf (int); @@ -963,7 +966,6 @@ class fhandler_dev_tape: public fhandler_dev_raw class fhandler_disk_file: public fhandler_base { HANDLE prw_handle; - bool mandatory_locking; int __reg3 readdir_helper (DIR *, dirent *, DWORD, DWORD, PUNICODE_STRING fname); int prw_open (bool); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 1b76a3488..075eac8ab 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1379,12 +1379,12 @@ fhandler_base::utimens_fs (const struct timespec *tvp) } fhandler_disk_file::fhandler_disk_file () : - fhandler_base (), prw_handle (NULL), mandatory_locking (false) + fhandler_base (), prw_handle (NULL) { } fhandler_disk_file::fhandler_disk_file (path_conv &pc) : - fhandler_base (), prw_handle (NULL), mandatory_locking (false) + fhandler_base (), prw_handle (NULL) { set_name (pc); } @@ -1415,7 +1415,8 @@ fhandler_disk_file::fcntl (int cmd, intptr_t arg) switch (cmd) { case F_LCK_MANDATORY: - mandatory_locking = !!arg; + mandatory_locking (!!arg); + need_fork_fixup (true); res = 0; break; case F_GETLK: @@ -1424,7 +1425,7 @@ fhandler_disk_file::fcntl (int cmd, intptr_t arg) { 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); + res = mandatory_locking () ? mand_lock (cmd, fl) : lock (cmd, fl); } break; default: @@ -1445,7 +1446,6 @@ fhandler_disk_file::dup (fhandler_base *child, int flags) GetCurrentProcess (), &fhc->prw_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) fhc->prw_handle = NULL; - fhc->mandatory_locking = mandatory_locking; return ret; } @@ -1453,7 +1453,7 @@ void fhandler_disk_file::fixup_after_fork (HANDLE parent) { prw_handle = NULL; - mandatory_locking = false; + mandatory_locking (false); fhandler_base::fixup_after_fork (parent); } diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index f7d19398b..c9d7eb6ea 100644 --- a/winsup/cygwin/flock.cc +++ b/winsup/cygwin/flock.cc @@ -918,6 +918,13 @@ 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, struct flock *) +{ + set_errno (EINVAL); + return -1; +} + int fhandler_disk_file::lock (int a_op, struct flock *fl) { @@ -1733,19 +1740,22 @@ flock (int fd, int operation) switch (operation & (~LOCK_NB)) { case LOCK_EX: - fl.l_type = F_WRLCK | F_FLOCK; + fl.l_type = F_WRLCK; break; case LOCK_SH: - fl.l_type = F_RDLCK | F_FLOCK; + fl.l_type = F_RDLCK; break; case LOCK_UN: - fl.l_type = F_UNLCK | F_FLOCK; + fl.l_type = F_UNLCK; break; default: set_errno (EINVAL); goto done; } - res = cfd->lock (cmd, &fl); + 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); done: @@ -1803,7 +1813,8 @@ lockf (int filedes, int function, off_t size) goto done; /* NOTREACHED */ } - res = cfd->lock (cmd, &fl); + res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl) + : cfd->lock (cmd, &fl); done: syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size); return res; @@ -1831,6 +1842,13 @@ blocking_lock_thr (LPVOID param) 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) { diff --git a/winsup/cygwin/release/1.7.19 b/winsup/cygwin/release/1.7.19 index 179eaa2e5..a73c916e6 100644 --- a/winsup/cygwin/release/1.7.19 +++ b/winsup/cygwin/release/1.7.19 @@ -10,8 +10,8 @@ What's new: - Add support for the AFS filesystem. -- Preliminary support for mandatory locking via fcntl, using Windows - locking semantics. New F_LCK_MANDATORY fcntl command. +- Support for mandatory locking via fcntl/flock/lockf, using Windows locking + semantics. New F_LCK_MANDATORY fcntl command. - New APIs: __b64_ntop, __b64_pton, arc4random, arc4random_addrandom, arc4random_buf, arc4random_stir, arc4random_uniform.