summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/flock.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-10-24 09:41:17 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-10-24 09:41:17 +0000
commit95ff6fc6da3cccb2b50600a181c6f9dcb1333283 (patch)
treec57705a56761f4d50cc518d78703f78036215ba6 /winsup/cygwin/flock.cc
parent72a386373e0fb620e943064f63f9e4d142c933d7 (diff)
downloadcygnal-95ff6fc6da3cccb2b50600a181c6f9dcb1333283.tar.gz
cygnal-95ff6fc6da3cccb2b50600a181c6f9dcb1333283.tar.bz2
cygnal-95ff6fc6da3cccb2b50600a181c6f9dcb1333283.zip
* devices.in (dev_storage): Map /dev/zero and /dev/full to \Device\Null.
* devices.cc: Regenerate. * dtable.h (struct dtable): Make fhandler_base friend, rather than fhandler_disk_file. * fhandler.cc (fhandler_base::open_with_arch): Create unique id. (fhandler_base::cleanup): Call del_my_locks. (fhandler_base::fcntl): Handle F_GETLK, F_SETLK and F_SETLKW. * fhandler.h (fhandler_base::get_dev): Return real device number. (fhandler_base::set_unique_id): New inline method. (fhandler_disk_file::lock): Drop declaration. (fhandler_disk_file::get_dev): New method, return pc.fs_serial_number. (fhandler_dev_zero::open): Drop declaration. * fhandler_disk_file.cc (fhandler_disk_file::close): Move del_my_locks call to fhandler_base::open_with_arch. (fhandler_disk_file::fcntl): Move handling of locking commands to fhandler_base::fcntl. (fhandler_base::open_fs): Drop call to NtAllocateLocallyUniqueId. * fhandler_zero.cc (fhandler_dev_zero::open): Remove so that default fhandler_base::open is used to open \Device\Null. * flock.cc (fixup_lockf_after_exec): Finding a single fhandler is enough here. (fhandler_base::lock): Replace fhandler_disk_file::lock. Refuse to lock nohandle devices. Handle read/write test using POSIX flags. Explain why. Never fail on SEEK_CUR or SEEK_END, rather assume position 0, just as Linux. * net.cc (fdsock): Create unique id.
Diffstat (limited to 'winsup/cygwin/flock.cc')
-rw-r--r--winsup/cygwin/flock.cc71
1 files changed, 41 insertions, 30 deletions
diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc
index 33f16af06..0cb2274d0 100644
--- a/winsup/cygwin/flock.cc
+++ b/winsup/cygwin/flock.cc
@@ -454,7 +454,7 @@ fixup_lockf_after_exec ()
while (cfd.next () >= 0)
if (cfd->get_dev () == node->i_dev
&& cfd->get_ino () == node->i_ino
- && ++cnt > 1)
+ && ++cnt >= 1)
break;
if (cnt == 0)
{
@@ -919,14 +919,7 @@ static void lf_wakelock (lockf_t *, HANDLE);
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)
+fhandler_base::lock (int a_op, struct flock *fl)
{
off_t start, end, oadd;
int error = 0;
@@ -934,6 +927,13 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
short a_flags = fl->l_type & (F_POSIX | F_FLOCK);
short type = fl->l_type & (F_RDLCK | F_WRLCK | F_UNLCK);
+ if (nohandle ())
+ {
+ set_errno (EINVAL);
+ debug_printf ("Locking on nohandle device, return EINVAL.");
+ return -1;
+ }
+
if (!a_flags)
a_flags = F_POSIX; /* default */
if (a_op == F_SETLKW)
@@ -952,16 +952,24 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
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. */
- if ((a_flags & F_POSIX) && !(get_access () & GENERIC_READ))
+ /* 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))
{
+ system_printf ("get_access() == %x", get_access ());
set_errno (EBADF);
return -1;
}
break;
case F_WRLCK:
/* See above comment. */
- if ((a_flags & F_POSIX) && !(get_access () & GENERIC_WRITE))
+ if ((a_flags & F_POSIX)
+ && ((get_flags () & O_ACCMODE) == O_RDONLY))
{
+ system_printf ("get_access() == %x", get_access ());
set_errno (EBADF);
return -1;
}
@@ -982,29 +990,32 @@ fhandler_disk_file::lock (int a_op, struct flock *fl)
case SEEK_CUR:
if ((start = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK)
- return -1;
+ start = 0;
break;
case SEEK_END:
- {
- NTSTATUS status;
- IO_STATUS_BLOCK io;
- FILE_STANDARD_INFORMATION fsi;
+ 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;
- }
+ 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: