mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 03:27:46 +08:00
* 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.
This commit is contained in:
parent
72a386373e
commit
95ff6fc6da
@ -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.
|
||||
|
@ -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},
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
----------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user