Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-10-24 13:41:17 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-10-24 13:41:17 +0400
commit95ff6fc6da3cccb2b50600a181c6f9dcb1333283 (patch)
treec57705a56761f4d50cc518d78703f78036215ba6 /winsup
parent72a386373e0fb620e943064f63f9e4d142c933d7 (diff)
* 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')
-rw-r--r--winsup/cygwin/ChangeLog29
-rw-r--r--winsup/cygwin/devices.cc4
-rw-r--r--winsup/cygwin/devices.in4
-rw-r--r--winsup/cygwin/dtable.h2
-rw-r--r--winsup/cygwin/fhandler.cc19
-rw-r--r--winsup/cygwin/fhandler.h6
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc17
-rw-r--r--winsup/cygwin/fhandler_zero.cc11
-rw-r--r--winsup/cygwin/flock.cc71
-rw-r--r--winsup/cygwin/net.cc5
-rw-r--r--winsup/cygwin/release/1.7.265
11 files changed, 109 insertions, 64 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7e201e5d6..d7974ad96 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,32 @@
+2013-10-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * 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.
+
2013-10-23 Corinna Vinschen <corinna@vinschen.de>
* include /cygwin/config.h (_READ_WRITE_BUFSIZE_TYPE): Define.
diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc
index 9f37ef827..fd2e7e16d 100644
--- a/winsup/cygwin/devices.cc
+++ b/winsup/cygwin/devices.cc
@@ -243,7 +243,7 @@ const _RDATA device dev_storage[] =
{"/dev/fd13", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 13)), "\\Device\\Floppy13", exists_ntdev, S_IFBLK, true},
{"/dev/fd14", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 14)), "\\Device\\Floppy14", exists_ntdev, S_IFBLK, true},
{"/dev/fd15", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 15)), "\\Device\\Floppy15", exists_ntdev, S_IFBLK, true},
- {"/dev/full", BRACK(FH_FULL), "/dev/full", exists, S_IFCHR, true},
+ {"/dev/full", BRACK(FH_FULL), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/kmsg", BRACK(FH_KMSG), "\\Device\\MailSlot\\cygwin\\dev\\kmsg", exists_ntdev, S_IFCHR, true},
{"/dev/nst0", BRACK(FHDEV(DEV_TAPE_MAJOR, 128)), "\\Device\\Tape0", exists_ntdev, S_IFBLK, true},
{"/dev/nst1", BRACK(FHDEV(DEV_TAPE_MAJOR, 129)), "\\Device\\Tape1", exists_ntdev, S_IFBLK, true},
@@ -2715,7 +2715,7 @@ const _RDATA device dev_storage[] =
{"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64", exists_ntdev, S_IFCHR, true},
{"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom", exists, S_IFCHR, true},
{"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows", exists, S_IFCHR, true},
- {"/dev/zero", BRACK(FH_ZERO), "/dev/zero", exists, S_IFCHR, true},
+ {"/dev/zero", BRACK(FH_ZERO), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{":fifo", BRACK(FH_FIFO), "/dev/fifo", exists_internal, S_IFCHR, false},
{":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR, false},
{":ptym0", BRACK(FHDEV(DEV_PTYM_MAJOR, 0)), "/dev/ptym0", exists_internal, S_IFCHR, false},
diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in
index 785aff0bf..ea26a5337 100644
--- a/winsup/cygwin/devices.in
+++ b/winsup/cygwin/devices.in
@@ -152,8 +152,8 @@ const device dev_error_storage =
"/dev/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR
"/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR
"/dev/null", BRACK(FH_NULL), "\\Device\\Null", exists_ntdev, S_IFCHR
-"/dev/zero", BRACK(FH_ZERO), "/dev/zero", exists, S_IFCHR
-"/dev/full", BRACK(FH_FULL), "/dev/full", exists, S_IFCHR
+"/dev/zero", BRACK(FH_ZERO), "\\Device\\Null", exists_ntdev, S_IFCHR
+"/dev/full", BRACK(FH_FULL), "\\Device\\Null", exists_ntdev, S_IFCHR
"/dev/random", BRACK(FH_RANDOM), "/dev/random", exists, S_IFCHR
"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom", exists, S_IFCHR, =urandom_dev
"/dev/clipboard", BRACK(FH_CLIPBOARD), "/dev/clipboard", exists, S_IFCHR
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 5fae60523..5810e04fe 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -90,7 +90,7 @@ public:
friend void dtable_init ();
friend void __stdcall close_all_files (bool);
friend int dup_finish (int, int, int);
- friend class fhandler_disk_file;
+ friend class fhandler_base;
friend class cygheap_fdmanip;
friend class cygheap_fdget;
friend class cygheap_fdnew;
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;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 73b5f4735..a0cdfa65c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -296,7 +296,7 @@ class fhandler_base
bool has_attribute (DWORD x) const {return pc.has_attribute (x);}
const char *get_name () const { return pc.normalized_path; }
const char *get_win32_name () { return pc.get_win32 (); }
- dev_t get_dev () { return pc.fs_serial_number (); }
+ virtual dev_t get_dev () { return get_device (); }
ino_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); }
long long get_unique_id () const { return unique_id; }
/* Returns name used for /proc/<pid>/fd in buf. */
@@ -312,6 +312,7 @@ class fhandler_base
int open_with_arch (int, mode_t = 0);
virtual int open (int, mode_t);
virtual void open_setup (int flags) { return; }
+ void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); }
int close_with_arch ();
virtual int close ();
@@ -979,7 +980,6 @@ class fhandler_disk_file: public fhandler_base
int fcntl (int cmd, intptr_t);
int dup (fhandler_base *child, int);
void fixup_after_fork (HANDLE parent);
- int lock (int, struct flock *);
int mand_lock (int, struct flock *);
bool isdevice () const { return false; }
int __reg2 fstat (struct stat *buf);
@@ -1012,6 +1012,7 @@ class fhandler_disk_file: public fhandler_base
ssize_t __reg3 pwrite (void *, size_t, off_t);
fhandler_disk_file (void *) {}
+ dev_t get_dev () { return pc.fs_serial_number (); }
void copyto (fhandler_base *x)
{
@@ -1618,7 +1619,6 @@ class fhandler_dev_zero: public fhandler_base
{
public:
fhandler_dev_zero ();
- int open (int flags, mode_t mode = 0);
ssize_t __stdcall write (const void *ptr, size_t len);
void __reg3 read (void *ptr, size_t& len);
off_t lseek (off_t offset, int whence);
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index fe321cda0..32f02bd5f 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1401,9 +1401,6 @@ fhandler_disk_file::close ()
/* Close extra pread/pwrite handle, if it exists. */
if (prw_handle)
NtClose (prw_handle);
- /* Delete all POSIX locks on the file. Delete all flock locks on the
- file if this is the last reference to this file. */
- del_my_locks (on_close);
return fhandler_base::close ();
}
@@ -1414,20 +1411,11 @@ fhandler_disk_file::fcntl (int cmd, intptr_t arg)
switch (cmd)
{
- case F_LCK_MANDATORY:
+ case F_LCK_MANDATORY: /* Mandatory locking only works on files. */
mandatory_locking (!!arg);
need_fork_fixup (true);
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:
res = fhandler_base::fcntl (cmd, arg);
break;
@@ -1487,9 +1475,6 @@ fhandler_base::open_fs (int flags, mode_t mode)
}
ino = pc.get_ino_by_handle (get_handle ());
- /* A unique ID is necessary to recognize fhandler entries which are
- duplicated by dup(2) or fork(2). */
- NtAllocateLocallyUniqueId ((PLUID) &unique_id);
out:
syscall_printf ("%d = fhandler_disk_file::open(%S, %y)", res,
diff --git a/winsup/cygwin/fhandler_zero.cc b/winsup/cygwin/fhandler_zero.cc
index 1fd874614..03319a7dd 100644
--- a/winsup/cygwin/fhandler_zero.cc
+++ b/winsup/cygwin/fhandler_zero.cc
@@ -1,6 +1,6 @@
/* fhandler_dev_zero.cc: code to access /dev/zero
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2013 Red Hat, Inc.
Written by DJ Delorie (dj@cygnus.com)
@@ -21,15 +21,6 @@ fhandler_dev_zero::fhandler_dev_zero ()
{
}
-int
-fhandler_dev_zero::open (int flags, mode_t)
-{
- set_flags ((flags & ~O_TEXT) | O_BINARY);
- nohandle (true);
- set_open_status ();
- return 1;
-}
-
ssize_t __stdcall
fhandler_dev_zero::write (const void *, size_t len)
{
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:
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 053c66718..e81de79c1 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -636,6 +636,11 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
system_printf ("getsockopt(SO_SNDBUF) failed, %u", WSAGetLastError ());
}
+ /* 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. */
+ ((fhandler_socket *) fd)->set_unique_id ();
+
return true;
}
diff --git a/winsup/cygwin/release/1.7.26 b/winsup/cygwin/release/1.7.26
index 378385527..3656715fa 100644
--- a/winsup/cygwin/release/1.7.26
+++ b/winsup/cygwin/release/1.7.26
@@ -7,6 +7,11 @@ What changed:
- Slightly improve randomness of /dev/random emulation.
+- Allow to use advisory locking on any device which is backed by an OS handle.
+ Right now this excludes /dev/clipboard, /dev/dsp, /dev/random, /dev/urandom,
+ as well as almost all virtual files under /proc.
+
+
Bug fixes:
----------