(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-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>
* exception.h: Fold in content of include/exceptions.h.
}
const device dev_cygdrive_storage =
- {"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists};
+ {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
#define BRACK(x) {devn_int: x}
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/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/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/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},
{":fifo", BRACK(FH_FIFO), "/dev/fifo", exists_internal, S_IFCHR, false},
{":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR, false},
}
const device dev_cygdrive_storage =
- {"/cygdrive", {FH_CYGDRIVE}, "/cygdrive", exists};
+ {"/cygdrive", {FH_CYGDRIVE}, "\\Device\\Null", exists};
const device dev_fs_storage =
{"", {FH_FS}, "", exists};
/* Internal devices below are prefixed with a ":". This moves them out of
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/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
"/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/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/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR
"/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR
/* dir.cc: Posix directory-related routines
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.
if (!res && fh)
delete fh;
+ /* Applications calling flock(2) on dirfd(fd) need this... */
+ if (!fh->nohandle ())
+ fh->set_unique_id ();
return res;
}
void rewinddir (DIR *);
fhandler_dev (void *) {}
+ dev_t get_dev () { return dir_exists ? pc.fs_serial_number ()
+ : get_device (); }
void copyto (fhandler_base *x)
{
public:
fhandler_cygdrive ();
int open (int flags, mode_t mode);
- int close ();
DIR __reg2 *opendir (int fd);
int __reg3 readdir (DIR *, dirent *);
void rewinddir (DIR *);
int __reg2 fstatvfs (struct statvfs *buf);
fhandler_cygdrive (void *) {}
+ dev_t get_dev () { return get_device (); }
void copyto (fhandler_base *x)
{
public:
fhandler_windows ();
int is_windows () { return 1; }
+ HWND get_hwnd () { return hWnd_; }
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, int) { 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_write (select_stuff *);
select_record *select_except (select_stuff *);
#include "dtable.h"
#include "cygheap.h"
#include "devices.h"
+#include "tls_pbuf.h"
#define _COMPILING_NEWLIB
#include <dirent.h>
set_errno (EISDIR);
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)
{
- flags |= O_DIROPEN;
- set_flags (flags);
- nohandle (true);
+ dir_exists = false;
+ /* Open a fake handle to \\Device\\Null, but revert to the old path
+ 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
fhandler_dev::close ()
{
- if (nohandle ())
- return 0;
return fhandler_disk_file::close ();
}
int ret = -1, opened = 0;
HANDLE fh = get_handle ();
- if (!fh && !nohandle ())
+ if (!fh)
{
if (!open (O_RDONLY, 0))
return -1;
opened = 1;
}
- if (!nohandle ())
+ if (pc.fs_got_fs ())
+ ret = fhandler_disk_file::fstatvfs (sfs);
+ else
{
- ret = fhandler_disk_file::fstatvfs (sfs);
- goto out;
+ /* Virtual file system. Just return an empty buffer with a few values
+ 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)
close ();
return ret;
DIR *
fhandler_dev::opendir (int fd)
{
- DIR *dir;
- DIR *res = NULL;
-
- dir = fhandler_disk_file::opendir (fd);
+ DIR *dir = fhandler_disk_file::opendir (fd);
if (dir)
- return dir;
- if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
+ dir_exists = true;
+ else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
set_errno (ENOMEM);
else if ((dir->__d_dirent =
(struct dirent *) malloc (sizeof (struct dirent))) == NULL)
if (fd >= 0)
dir->__d_fd = fd;
+ else if (!open (O_RDONLY, 0))
+ goto free_dirent;
else
{
cfd = this;
dir->__d_fd = cfd;
- cfd->nohandle (true);
}
set_close_on_exec (true);
dir->__fh = this;
- devidx = dev_storage_scan_start;
- res = dir;
+ dir_exists = false;
}
- syscall_printf ("%p = opendir (%s)", res, get_name ());
- return res;
+ devidx = dir_exists ? NULL : dev_storage_scan_start;
+
+ syscall_printf ("%p = opendir (%s)", dir, get_name ());
+ return dir;
free_dirent:
free (dir->__d_dirent);
free_dir:
free (dir);
- return res;
+ return NULL;
}
int
fhandler_dev::rewinddir (DIR *dir)
{
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);
}
dir->__d_position = 0;
dir->__flags = (get_name ()[0] == '/' && get_name ()[1] == '\0')
? dirent_isroot : 0;
- dir->__d_internal = (uintptr_t) new __DIR_mounts (get_name ());
- d_cachepos (dir) = 0;
+ dir->__d_internal = 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)
{
/* opendir() case. Initialize with given directory name and
time on exit. Nasty, nasty... */
cfd = this;
dir->__d_fd = cfd;
- if (pc.iscygdrive ())
- cfd->nohandle (true);
}
set_close_on_exec (true);
dir->__fh = this;
set_errno (EISDIR);
return 0;
}
- flags |= O_DIROPEN;
- set_flags (flags);
- nohandle (true);
- return 1;
-}
-
-int
-fhandler_cygdrive::close ()
-{
- return 0;
+ /* Open a fake handle to \\Device\\Null, but revert to the old path
+ 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);
+ int ret = fhandler_base::open (flags, mode);
+ pc.set_path (orig_path);
+ return ret;
}
void
set to something useful. Just as on Linux. */
memset (sfs, 0, sizeof (*sfs));
sfs->f_bsize = sfs->f_frsize = 4096;
+ sfs->f_flag = ST_RDONLY;
sfs->f_namemax = NAME_MAX;
return 0;
}
/* fhandler_windows.cc: code to access windows message queues.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012
- Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2011, 2012,
+ 2013 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru).
Feedback and testing by Andy Piper (andyp@parallax.co.uk).
}
int
-fhandler_windows::open (int flags, mode_t)
+fhandler_windows::open (int flags, mode_t mode)
{
- set_flags ((flags & ~O_TEXT) | O_BINARY);
- close_on_exec (true);
- set_open_status ();
- return 1;
+ return fhandler_base::open ((flags & ~O_TEXT) | O_BINARY, mode);
}
ssize_t __stdcall
return;
}
- HANDLE w4[3] = { get_handle (), };
- set_signal_arrived here (w4[1]);
- DWORD cnt = 2;
- if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
+ HANDLE w4[2];
+ set_signal_arrived here (w4[0]);
+ DWORD cnt = 1;
+ if ((w4[1] = pthread::get_cancel_event ()) != NULL)
++cnt;
for (;;)
{
MWMO_INPUTAVAILABLE))
{
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))
{
len = (size_t) -1;
else
len = sizeof (MSG);
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:
len = (size_t) -1;
set_errno (EAGAIN);
}
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_");
-}
cfree (modifiable_path ());
char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7);
strcpy (new_path, p);
+ cfree_and_null (wide_path);
return path = new_path;
}
bool is_binary ();
MSG m;
HANDLE h;
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)
return 1;
s->peek = peek_windows;
s->read_selected = true;
s->read_ready = false;
- s->h = get_handle ();
s->windows_handle = true;
return s;
}
s->verify = verify_ok;
}
s->peek = peek_windows;
- s->h = get_handle ();
s->write_selected = true;
s->write_ready = true;
s->windows_handle = true;
s->verify = verify_ok;
}
s->peek = peek_windows;
- s->h = get_handle ();
s->except_selected = true;
s->except_ready = false;
s->windows_handle = true;