* devices.in (dev_cygdrive_storage): Map to \Device\Null.

(dev_storage): Map /dev and /dev/windows to \Device\Null.
	* devices.cc: Regenerate.
	* dir.cc (opendir): Create unique id.  Explain why.
	* fhandler.h (fhandler_dev::get_dev): Implement inline.
	(fhandler_cygdrive::close): Drop declaration.
	(fhandler_cygdrive::get_dev): Implement inline.
	(fhandler_windows::get_hwnd): Ditto.
	(fhandler_windows::set_close_on_exec): Drop declaration.
	(fhandler_windows::fixup_after_fork): Ditto.
	* fhandler_dev.cc (fhandler_dev::open): Call fhandler_disk_file::open
	without O_CREAT flag.  Explain why.  Create \Device\Null handle if
	/dev/ doesn't actually exist.
	(fhandler_dev::close): Drop nohandle case.
	(fhandler_dev::fstatvfs): Drop nohandle check.  Test for fs_got_fs
	instead.  Set ST_RDONLY fs flag for simulated /dev.
	(fhandler_dev::opendir): If /dev doesn't exist, call open() to create
	fake \Device\Null handle.  Don't set nohandle.  Set dir_exists
	correctly.
	(fhandler_dev::rewinddir): Call fhandler_disk_file::rewinddir only if
	/dev is a real directory.
	* fhandler_disk_file.cc (fhandler_disk_file::opendir): If called for
	the cygdrive dir, call open() to create fake \Device\Null handle.
	Only attach __DIR_mounts buffer to dir if not called for cygdrive dir.
	Don't set nohandle.
	(fhandler_cygdrive::open): Create \Device\Null handle.
	(fhandler_cygdrive::close): Remove.
	(fhandler_cygdrive::fstatvfs): Set ST_RDONLY fs flag.
	* fhandler_windows.cc (fhandler_windows::open): Create \Device\Null
	handle.
	(fhandler_windows::read): Don't add io_handle to WFMO handle array.
	Change subsequent test for return value accordingly.  Fix test for
	"message arrived".
	(fhandler_windows::set_close_on_exec): Remove.
	(fhandler_windows::fixup_after_fork): Remove.
	* path.h (path_conv::set_path): Make sure wide_path is NULL when
	setting a new path.
	* select.cc (peek_windows): Use correct hWnd value, not io_handle.
	(fhandler_windows::select_read): Don't use io_handle as wait object.
	(fhandler_windows::select_write): Ditto.
	(fhandler_windows::select_except): Ditto.
This commit is contained in:
Corinna Vinschen 2013-10-30 09:44:47 +00:00
parent 0160e166ee
commit 751bbaf96a
10 changed files with 141 additions and 102 deletions

View File

@ -1,3 +1,47 @@
2013-10-30 Corinna Vinschen <corinna@vinschen.de>
* devices.in (dev_cygdrive_storage): Map to \Device\Null.
(dev_storage): Map /dev and /dev/windows to \Device\Null.
* devices.cc: Regenerate.
* dir.cc (opendir): Create unique id. Explain why.
* fhandler.h (fhandler_dev::get_dev): Implement inline.
(fhandler_cygdrive::close): Drop declaration.
(fhandler_cygdrive::get_dev): Implement inline.
(fhandler_windows::get_hwnd): Ditto.
(fhandler_windows::set_close_on_exec): Drop declaration.
(fhandler_windows::fixup_after_fork): Ditto.
* fhandler_dev.cc (fhandler_dev::open): Call fhandler_disk_file::open
without O_CREAT flag. Explain why. Create \Device\Null handle if
/dev/ doesn't actually exist.
(fhandler_dev::close): Drop nohandle case.
(fhandler_dev::fstatvfs): Drop nohandle check. Test for fs_got_fs
instead. Set ST_RDONLY fs flag for simulated /dev.
(fhandler_dev::opendir): If /dev doesn't exist, call open() to create
fake \Device\Null handle. Don't set nohandle. Set dir_exists
correctly.
(fhandler_dev::rewinddir): Call fhandler_disk_file::rewinddir only if
/dev is a real directory.
* fhandler_disk_file.cc (fhandler_disk_file::opendir): If called for
the cygdrive dir, call open() to create fake \Device\Null handle.
Only attach __DIR_mounts buffer to dir if not called for cygdrive dir.
Don't set nohandle.
(fhandler_cygdrive::open): Create \Device\Null handle.
(fhandler_cygdrive::close): Remove.
(fhandler_cygdrive::fstatvfs): Set ST_RDONLY fs flag.
* fhandler_windows.cc (fhandler_windows::open): Create \Device\Null
handle.
(fhandler_windows::read): Don't add io_handle to WFMO handle array.
Change subsequent test for return value accordingly. Fix test for
"message arrived".
(fhandler_windows::set_close_on_exec): Remove.
(fhandler_windows::fixup_after_fork): Remove.
* path.h (path_conv::set_path): Make sure wide_path is NULL when
setting a new path.
* select.cc (peek_windows): Use correct hWnd value, not io_handle.
(fhandler_windows::select_read): Don't use io_handle as wait object.
(fhandler_windows::select_write): Ditto.
(fhandler_windows::select_except): Ditto.
2013-10-27 Corinna Vinschen <corinna@vinschen.de> 2013-10-27 Corinna Vinschen <corinna@vinschen.de>
* exception.h: Fold in content of include/exceptions.h. * exception.h: Fold in content of include/exceptions.h.

View File

@ -91,7 +91,7 @@ exists_pty (const device& dev)
} }
const device dev_cygdrive_storage = const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists}; {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
const device dev_fs_storage = const device dev_fs_storage =
{"", {FH_FS}, "", exists}; {"", {FH_FS}, "", exists};
@ -141,7 +141,7 @@ const device dev_error_storage =
#define BRACK(x) {devn_int: x} #define BRACK(x) {devn_int: x}
const _RDATA device dev_storage[] = const _RDATA device dev_storage[] =
{ {
{"/dev", BRACK(FH_DEV), "/dev", exists, S_IFDIR, false}, {"/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR, false},
{"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR, true}, {"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1", exists_ntdev_silent, S_IFCHR, true}, {"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1", exists_ntdev_silent, S_IFCHR, true},
{"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2", exists_ntdev_silent, S_IFCHR, true}, {"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2", exists_ntdev_silent, S_IFCHR, true},
@ -2714,7 +2714,7 @@ const _RDATA device dev_storage[] =
{"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63", exists_ntdev, S_IFCHR, true}, {"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63", exists_ntdev, S_IFCHR, true},
{"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64", exists_ntdev, S_IFCHR, true}, {"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64", exists_ntdev, S_IFCHR, true},
{"/dev/urandom", BRACK(FH_URANDOM), "\\Device\\Null", exists_ntdev, S_IFCHR, true}, {"/dev/urandom", BRACK(FH_URANDOM), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows", exists, S_IFCHR, true}, {"/dev/windows", BRACK(FH_WINDOWS), "\\Device\\Null", exists_ntdev, S_IFCHR, true},
{"/dev/zero", BRACK(FH_ZERO), "\\Device\\Null", exists_ntdev, 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}, {":fifo", BRACK(FH_FIFO), "/dev/fifo", exists_internal, S_IFCHR, false},
{":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR, false}, {":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR, false},

View File

@ -87,7 +87,7 @@ exists_pty (const device& dev)
} }
const device dev_cygdrive_storage = const device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists}; {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
const device dev_fs_storage = const device dev_fs_storage =
{"", {FH_FS}, "", exists}; {"", {FH_FS}, "", exists};
@ -140,14 +140,14 @@ const device dev_error_storage =
/* Internal devices below are prefixed with a ":". This moves them out of /* Internal devices below are prefixed with a ":". This moves them out of
the POSIX namespace. */ the POSIX namespace. */
%% %%
"/dev", BRACK(FH_DEV), "/dev", exists, S_IFDIR "/dev", BRACK(FH_DEV), "\\Device\\Null", exists, S_IFDIR
"/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR "/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR
"/dev/pty%(0-63)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev "/dev/pty%(0-63)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev
":ptym%(0-63)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev ":ptym%(0-63)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev
"/dev/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", exists_console, S_IFCHR, =cons_dev "/dev/cons%(0-63)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", exists_console, S_IFCHR, =cons_dev
"/dev/console", BRACK(FH_CONSOLE), "/dev/console", exists_console, S_IFCHR, =console_dev "/dev/console", BRACK(FH_CONSOLE), "/dev/console", exists_console, S_IFCHR, =console_dev
"/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx", exists, S_IFCHR "/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx", exists, S_IFCHR
"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows", exists, S_IFCHR "/dev/windows", BRACK(FH_WINDOWS), "\\Device\\Null", exists_ntdev, S_IFCHR
"/dev/dsp", BRACK(FH_OSS_DSP), "\\Device\\Null", exists_ntdev, S_IFCHR "/dev/dsp", BRACK(FH_OSS_DSP), "\\Device\\Null", exists_ntdev, S_IFCHR
"/dev/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR "/dev/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR
"/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR "/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR

View File

@ -1,7 +1,7 @@
/* dir.cc: Posix directory-related routines /* dir.cc: Posix directory-related routines
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -68,6 +68,9 @@ opendir (const char *name)
if (!res && fh) if (!res && fh)
delete fh; delete fh;
/* Applications calling flock(2) on dirfd(fd) need this... */
if (!fh->nohandle ())
fh->set_unique_id ();
return res; return res;
} }

View File

@ -1045,6 +1045,8 @@ public:
void rewinddir (DIR *); void rewinddir (DIR *);
fhandler_dev (void *) {} fhandler_dev (void *) {}
dev_t get_dev () { return dir_exists ? pc.fs_serial_number ()
: get_device (); }
void copyto (fhandler_base *x) void copyto (fhandler_base *x)
{ {
@ -1075,7 +1077,6 @@ class fhandler_cygdrive: public fhandler_disk_file
public: public:
fhandler_cygdrive (); fhandler_cygdrive ();
int open (int flags, mode_t mode); int open (int flags, mode_t mode);
int close ();
DIR __reg2 *opendir (int fd); DIR __reg2 *opendir (int fd);
int __reg3 readdir (DIR *, dirent *); int __reg3 readdir (DIR *, dirent *);
void rewinddir (DIR *); void rewinddir (DIR *);
@ -1084,6 +1085,7 @@ class fhandler_cygdrive: public fhandler_disk_file
int __reg2 fstatvfs (struct statvfs *buf); int __reg2 fstatvfs (struct statvfs *buf);
fhandler_cygdrive (void *) {} fhandler_cygdrive (void *) {}
dev_t get_dev () { return get_device (); }
void copyto (fhandler_base *x) void copyto (fhandler_base *x)
{ {
@ -1726,6 +1728,7 @@ class fhandler_windows: public fhandler_base
public: public:
fhandler_windows (); fhandler_windows ();
int is_windows () { return 1; } int is_windows () { return 1; }
HWND get_hwnd () { return hWnd_; }
int open (int flags, mode_t mode = 0); int open (int flags, mode_t mode = 0);
ssize_t __stdcall write (const void *ptr, size_t len); ssize_t __stdcall write (const void *ptr, size_t len);
void __reg3 read (void *ptr, size_t& len); void __reg3 read (void *ptr, size_t& len);
@ -1733,8 +1736,6 @@ class fhandler_windows: public fhandler_base
off_t lseek (off_t, int) { return 0; } off_t lseek (off_t, int) { return 0; }
int close () { return 0; } int close () { return 0; }
void set_close_on_exec (bool val);
void fixup_after_fork (HANDLE parent);
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);

View File

@ -16,6 +16,7 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "devices.h" #include "devices.h"
#include "tls_pbuf.h"
#define _COMPILING_NEWLIB #define _COMPILING_NEWLIB
#include <dirent.h> #include <dirent.h>
@ -49,21 +50,27 @@ fhandler_dev::open (int flags, mode_t mode)
set_errno (EISDIR); set_errno (EISDIR);
return 0; return 0;
} }
int ret = fhandler_disk_file::open (flags, mode); /* Filter O_CREAT flag to avoid creating a file called /dev accidentally. */
int ret = fhandler_disk_file::open (flags & ~O_CREAT, mode);
if (!ret) if (!ret)
{ {
flags |= O_DIROPEN; dir_exists = false;
set_flags (flags); /* Open a fake handle to \\Device\\Null, but revert to the old path
nohandle (true); string afterwards, otherwise readdir will return with an EFAULT
when trying to fetch the inode number of ".." */
tmp_pathbuf tp;
char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
pc.set_path (dev ().native);
ret = fhandler_base::open (flags, mode);
pc.set_path (orig_path);
} }
return 1; return ret;
} }
int int
fhandler_dev::close () fhandler_dev::close ()
{ {
if (nohandle ())
return 0;
return fhandler_disk_file::close (); return fhandler_disk_file::close ();
} }
@ -87,25 +94,24 @@ fhandler_dev::fstatvfs (struct statvfs *sfs)
int ret = -1, opened = 0; int ret = -1, opened = 0;
HANDLE fh = get_handle (); HANDLE fh = get_handle ();
if (!fh && !nohandle ()) if (!fh)
{ {
if (!open (O_RDONLY, 0)) if (!open (O_RDONLY, 0))
return -1; return -1;
opened = 1; opened = 1;
} }
if (!nohandle ()) if (pc.fs_got_fs ())
ret = fhandler_disk_file::fstatvfs (sfs);
else
{ {
ret = fhandler_disk_file::fstatvfs (sfs); /* Virtual file system. Just return an empty buffer with a few values
goto out; set to something useful similar to Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX;
ret = 0;
} }
/* Virtual file system. Just return an empty buffer with a few values
set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_namemax = NAME_MAX;
ret = 0;
out:
if (opened) if (opened)
close (); close ();
return ret; return ret;
@ -114,13 +120,10 @@ out:
DIR * DIR *
fhandler_dev::opendir (int fd) fhandler_dev::opendir (int fd)
{ {
DIR *dir; DIR *dir = fhandler_disk_file::opendir (fd);
DIR *res = NULL;
dir = fhandler_disk_file::opendir (fd);
if (dir) if (dir)
return dir; dir_exists = true;
if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL) else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
set_errno (ENOMEM); set_errno (ENOMEM);
else if ((dir->__d_dirent = else if ((dir->__d_dirent =
(struct dirent *) malloc (sizeof (struct dirent))) == NULL) (struct dirent *) malloc (sizeof (struct dirent))) == NULL)
@ -144,26 +147,28 @@ fhandler_dev::opendir (int fd)
if (fd >= 0) if (fd >= 0)
dir->__d_fd = fd; dir->__d_fd = fd;
else if (!open (O_RDONLY, 0))
goto free_dirent;
else else
{ {
cfd = this; cfd = this;
dir->__d_fd = cfd; dir->__d_fd = cfd;
cfd->nohandle (true);
} }
set_close_on_exec (true); set_close_on_exec (true);
dir->__fh = this; dir->__fh = this;
devidx = dev_storage_scan_start; dir_exists = false;
res = dir;
} }
syscall_printf ("%p = opendir (%s)", res, get_name ()); devidx = dir_exists ? NULL : dev_storage_scan_start;
return res;
syscall_printf ("%p = opendir (%s)", dir, get_name ());
return dir;
free_dirent: free_dirent:
free (dir->__d_dirent); free (dir->__d_dirent);
free_dir: free_dir:
free (dir); free (dir);
return res; return NULL;
} }
int int
@ -226,5 +231,7 @@ void
fhandler_dev::rewinddir (DIR *dir) fhandler_dev::rewinddir (DIR *dir)
{ {
devidx = dir_exists ? NULL : dev_storage_scan_start; devidx = dir_exists ? NULL : dev_storage_scan_start;
fhandler_disk_file::rewinddir (dir); dir->__d_position = 0;
if (dir_exists)
fhandler_disk_file::rewinddir (dir);
} }

View File

@ -1833,11 +1833,17 @@ fhandler_disk_file::opendir (int fd)
dir->__d_position = 0; dir->__d_position = 0;
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0') dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
? dirent_isroot : 0; ? dirent_isroot : 0;
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ()); dir->__d_internal = 0;
d_cachepos (dir) = 0;
if (!pc.iscygdrive ()) if (pc.iscygdrive ())
{ {
if (fd < 0 && !open (O_RDONLY, 0))
goto free_mounts;
}
else
{
dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
d_cachepos (dir) = 0;
if (fd < 0) if (fd < 0)
{ {
/* opendir() case. Initialize with given directory name and /* opendir() case. Initialize with given directory name and
@ -1918,8 +1924,6 @@ fhandler_disk_file::opendir (int fd)
time on exit. Nasty, nasty... */ time on exit. Nasty, nasty... */
cfd = this; cfd = this;
dir->__d_fd = cfd; dir->__d_fd = cfd;
if (pc.iscygdrive ())
cfd->nohandle (true);
} }
set_close_on_exec (true); set_close_on_exec (true);
dir->__fh = this; dir->__fh = this;
@ -2380,16 +2384,16 @@ fhandler_cygdrive::open (int flags, mode_t mode)
set_errno (EISDIR); set_errno (EISDIR);
return 0; return 0;
} }
flags |= O_DIROPEN; /* Open a fake handle to \\Device\\Null, but revert to the old path
set_flags (flags); string afterwards, otherwise readdir will return with an EFAULT
nohandle (true); when trying to fetch the inode number of ".." */
return 1; tmp_pathbuf tp;
} char *orig_path = tp.c_get ();
stpcpy (orig_path, get_win32_name ());
int pc.set_path (dev ().native);
fhandler_cygdrive::close () int ret = fhandler_base::open (flags, mode);
{ pc.set_path (orig_path);
return 0; return ret;
} }
void void
@ -2416,6 +2420,7 @@ fhandler_cygdrive::fstatvfs (struct statvfs *sfs)
set to something useful. Just as on Linux. */ set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs)); memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096; sfs->f_bsize = sfs->f_frsize = 4096;
sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX; sfs->f_namemax = NAME_MAX;
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
/* fhandler_windows.cc: code to access windows message queues. /* fhandler_windows.cc: code to access windows message queues.
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012,
Red Hat, Inc. 2013 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru). Written by Sergey S. Okhapkin (sos@prospect.com.ru).
Feedback and testing by Andy Piper (andyp@parallax.co.uk). Feedback and testing by Andy Piper (andyp@parallax.co.uk).
@ -54,12 +54,9 @@ fhandler_windows::fhandler_windows ()
} }
int int
fhandler_windows::open (int flags, mode_t) fhandler_windows::open (int flags, mode_t mode)
{ {
set_flags ((flags & ~O_TEXT) | O_BINARY); return fhandler_base::open ((flags & ~O_TEXT) | O_BINARY, mode);
close_on_exec (true);
set_open_status ();
return 1;
} }
ssize_t __stdcall ssize_t __stdcall
@ -96,10 +93,10 @@ fhandler_windows::read (void *buf, size_t& len)
return; return;
} }
HANDLE w4[3] = { get_handle (), }; HANDLE w4[2];
set_signal_arrived here (w4[1]); set_signal_arrived here (w4[0]);
DWORD cnt = 2; DWORD cnt = 1;
if ((w4[cnt] = pthread::get_cancel_event ()) != NULL) if ((w4[1] = pthread::get_cancel_event ()) != NULL)
++cnt; ++cnt;
for (;;) for (;;)
{ {
@ -109,6 +106,19 @@ fhandler_windows::read (void *buf, size_t& len)
MWMO_INPUTAVAILABLE)) MWMO_INPUTAVAILABLE))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
if (_my_tls.call_signal_handler ())
continue;
len = (size_t) -1;
set_errno (EINTR);
break;
case WAIT_OBJECT_0 + 1:
if (cnt > 1) /* WAIT_OBJECT_0 + 1 is the cancel event object. */
{
pthread::static_cancel_self ();
break;
}
/*FALLTHRU*/
case WAIT_OBJECT_0 + 2:
if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE)) if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
{ {
len = (size_t) -1; len = (size_t) -1;
@ -119,15 +129,6 @@ fhandler_windows::read (void *buf, size_t& len)
else else
len = sizeof (MSG); len = sizeof (MSG);
break; break;
case WAIT_OBJECT_0 + 1:
if (_my_tls.call_signal_handler ())
continue;
len = (size_t) -1;
set_errno (EINTR);
break;
case WAIT_OBJECT_0 + 2:
pthread::static_cancel_self ();
break;
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
len = (size_t) -1; len = (size_t) -1;
set_errno (EAGAIN); set_errno (EAGAIN);
@ -163,25 +164,3 @@ fhandler_windows::ioctl (unsigned int cmd, void *val)
} }
return 0; return 0;
} }
void
fhandler_windows::set_close_on_exec (bool val)
{
if (get_handle ())
fhandler_base::set_close_on_exec (val);
else
fhandler_base::close_on_exec (val);
void *h = hWnd_;
if (h)
set_no_inheritance (h, val);
}
void
fhandler_windows::fixup_after_fork (HANDLE parent)
{
if (get_handle ())
fhandler_base::fixup_after_fork (parent);
void *h = hWnd_;
if (h)
fork_fixup (parent, h, "hWnd_");
}

View File

@ -380,6 +380,7 @@ class path_conv
cfree (modifiable_path ()); cfree (modifiable_path ());
char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7); char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7);
strcpy (new_path, p); strcpy (new_path, p);
cfree_and_null (wide_path);
return path = new_path; return path = new_path;
} }
bool is_binary (); bool is_binary ();

View File

@ -1542,6 +1542,8 @@ peek_windows (select_record *me, bool)
MSG m; MSG m;
HANDLE h; HANDLE h;
set_handle_or_return_if_not_open (h, me); set_handle_or_return_if_not_open (h, me);
/* We need the hWnd value, not the io_handle. */
h = ((fhandler_windows *) me->fh)->get_hwnd ();
if (me->read_selected && me->read_ready) if (me->read_selected && me->read_ready)
return 1; return 1;
@ -1576,7 +1578,6 @@ fhandler_windows::select_read (select_stuff *ss)
s->peek = peek_windows; s->peek = peek_windows;
s->read_selected = true; s->read_selected = true;
s->read_ready = false; s->read_ready = false;
s->h = get_handle ();
s->windows_handle = true; s->windows_handle = true;
return s; return s;
} }
@ -1591,7 +1592,6 @@ fhandler_windows::select_write (select_stuff *ss)
s->verify = verify_ok; s->verify = verify_ok;
} }
s->peek = peek_windows; s->peek = peek_windows;
s->h = get_handle ();
s->write_selected = true; s->write_selected = true;
s->write_ready = true; s->write_ready = true;
s->windows_handle = true; s->windows_handle = true;
@ -1608,7 +1608,6 @@ fhandler_windows::select_except (select_stuff *ss)
s->verify = verify_ok; s->verify = verify_ok;
} }
s->peek = peek_windows; s->peek = peek_windows;
s->h = get_handle ();
s->except_selected = true; s->except_selected = true;
s->except_ready = false; s->except_ready = false;
s->windows_handle = true; s->windows_handle = true;