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
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-05-18 00:34:15 +0400
committerCorinna Vinschen <corinna@vinschen.de>2005-05-18 00:34:15 +0400
commit5b59a2cc0d956943b22b8dc6282d69bd06c231d1 (patch)
treef153307b3981c7e77d554753d94baded92fdd697
parent0d5ba26ccd9355696daffb76f465f29abd714b10 (diff)
* fhandler.h (class fhandler_netdrive): Add method rewinddir.
* fhandler_netdrive.cc (struct netdriveinf): New structure to store thread arguments. (thread_netdrive): Thread handling all potentially blocking WNet... calls. (create_thread_and_wait): Start and wait for above thread. (fhandler_netdrive::exists): Change to call create_thread_and_wait instead of calling WNet... function. (fhandler_netdrive::readdir): Ditto. Fix error handling. (fhandler_netdrive::rewinddir): New method.
-rw-r--r--winsup/cygwin/ChangeLog13
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_netdrive.cc138
3 files changed, 116 insertions, 36 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fbce5e289..8d4e9745e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,18 @@
2005-05-17 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler.h (class fhandler_netdrive): Add method rewinddir.
+ * fhandler_netdrive.cc (struct netdriveinf): New structure to
+ store thread arguments.
+ (thread_netdrive): Thread handling all potentially blocking
+ WNet... calls.
+ (create_thread_and_wait): Start and wait for above thread.
+ (fhandler_netdrive::exists): Change to call create_thread_and_wait
+ instead of calling WNet... function.
+ (fhandler_netdrive::readdir): Ditto. Fix error handling.
+ (fhandler_netdrive::rewinddir): New method.
+
+2005-05-17 Corinna Vinschen <corinna@vinschen.de>
+
* external.cc (cygwin_internal): Avoid compiler warning.
2005-05-16 Christopher Faylor <cgf@timesys.com>
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index be7a6c38b..c8e7217fa 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1222,6 +1222,7 @@ class fhandler_netdrive: public fhandler_virtual
struct dirent *readdir (DIR *);
_off64_t telldir (DIR *);
void seekdir (DIR *, _off64_t);
+ void rewinddir (DIR *);
int closedir (DIR *);
int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc
index b1a6e8926..c778a7d90 100644
--- a/winsup/cygwin/fhandler_netdrive.cc
+++ b/winsup/cygwin/fhandler_netdrive.cc
@@ -18,11 +18,90 @@ details. */
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
+#include "sigproc.h"
+#include "cygthread.h"
#include <assert.h>
#include <winnetwk.h>
#include <dirent.h>
+enum
+ {
+ GET_RESOURCE_INFO = 0,
+ GET_RESOURCE_OPENENUM = 1,
+ GET_RESOURCE_OPENENUMTOP = 2,
+ GET_RESOURCE_ENUM = 3
+ };
+
+struct netdriveinf
+ {
+ int what;
+ int ret;
+ PVOID in;
+ PVOID out;
+ DWORD outsize;
+ HANDLE sem;
+ };
+
+static DWORD WINAPI
+thread_netdrive (void *arg)
+{
+ netdriveinf *ndi = (netdriveinf *) arg;
+ LPTSTR dummy = NULL;
+ LPNETRESOURCE nro, nro2;
+ DWORD size;
+ HANDLE enumhdl;
+
+ ReleaseSemaphore (ndi->sem, 1, NULL);
+ switch (ndi->what)
+ {
+ case GET_RESOURCE_INFO:
+ nro = (LPNETRESOURCE) alloca (size = 4096);
+ ndi->ret = WNetGetResourceInformation ((LPNETRESOURCE) ndi->in,
+ nro, &size, &dummy);
+ break;
+ case GET_RESOURCE_OPENENUM:
+ case GET_RESOURCE_OPENENUMTOP:
+ nro = (LPNETRESOURCE) alloca (size = 4096);
+ ndi->ret = WNetGetResourceInformation ((LPNETRESOURCE) ndi->in,
+ nro, &size, &dummy);
+ if (ndi->ret != NO_ERROR)
+ break;
+ if (ndi->what == GET_RESOURCE_OPENENUMTOP)
+ {
+ nro2 = nro;
+ nro = (LPNETRESOURCE) alloca (size = 4096);
+ ndi->ret = WNetGetResourceParent (nro2, nro, &size);
+ if (ndi->ret != NO_ERROR)
+ break;
+ }
+ ndi->ret = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, nro,
+ &enumhdl);
+ if (ndi->ret == NO_ERROR)
+ *(HANDLE *) ndi->out = enumhdl;
+ break;
+ case GET_RESOURCE_ENUM:
+ ndi->ret = WNetEnumResource ((HANDLE) ndi->in, (size = 1, &size),
+ (LPNETRESOURCE) ndi->out, &ndi->outsize);
+ break;
+ }
+ ReleaseSemaphore (ndi->sem, 1, NULL);
+ return 0;
+}
+
+static DWORD
+create_thread_and_wait (int what, PVOID in, PVOID out, DWORD outsize,
+ const char *name)
+{
+ netdriveinf ndi = { what, 0, in, out, outsize,
+ CreateSemaphore (&sec_none_nih, 0, 2, NULL) };
+ cygthread *thr = new cygthread (thread_netdrive, (LPVOID) &ndi, name);
+ if (thr->detach (ndi.sem))
+ ndi.ret = ERROR_OPERATION_ABORTED;
+ CloseHandle (ndi.sem);
+ return ndi.ret;
+}
+
/* Returns 0 if path doesn't exist, >0 if path is a directory,
-1 if path is a file, -2 if it's a symlink. */
int
@@ -43,11 +122,9 @@ fhandler_netdrive::exists ()
nr.dwType = RESOURCETYPE_DISK;
nr.lpLocalName = NULL;
nr.lpRemoteName = namebuf;
- LPTSTR sys = NULL;
- char buf[8192];
- DWORD n = sizeof (buf);
- DWORD rc = WNetGetResourceInformation (&nr, &buf, &n, &sys);
- if (rc != ERROR_MORE_DATA && rc != NO_ERROR)
+ DWORD ret = create_thread_and_wait (GET_RESOURCE_INFO, &nr, NULL, 0,
+ "WnetGetResourceInformation");
+ if (ret != ERROR_MORE_DATA && ret != NO_ERROR)
return 0;
return 1;
}
@@ -80,8 +157,8 @@ fhandler_netdrive::readdir (DIR *dir)
if (!dir->__d_position)
{
size_t len = strlen (get_name ());
- char *namebuf, *dummy;
- NETRESOURCE nr = { 0 }, *nro2;
+ char *namebuf;
+ NETRESOURCE nr = { 0 };
if (len == 2) /* // */
{
@@ -106,44 +183,24 @@ fhandler_netdrive::readdir (DIR *dir)
nr.lpRemoteName = namebuf;
nr.dwType = RESOURCETYPE_DISK;
- size = 4096;
- nro = (NETRESOURCE *) alloca (size);
- ret = WNetGetResourceInformation (&nr, nro, &size, &dummy);
+ nro = (NETRESOURCE *) alloca (4096);
+ ret = create_thread_and_wait (len == 2 ? GET_RESOURCE_OPENENUMTOP
+ : GET_RESOURCE_OPENENUM,
+ &nr, &dir->__handle, 0, "WNetOpenEnum");
if (ret != NO_ERROR)
{
- __seterrno ();
- return NULL;
- }
-
- if (len == 2)
- {
- nro2 = nro;
- size = 4096;
- nro = (NETRESOURCE *) alloca (size);
- ret = WNetGetResourceParent (nro2, nro, &size);
- if (ret != NO_ERROR)
- {
- __seterrno ();
- return NULL;
- }
- }
- ret = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0,
- nro, &dir->__handle);
- if (ret != NO_ERROR)
- {
- __seterrno ();
+ __seterrno_from_win_error (ret);
dir->__handle = INVALID_HANDLE_VALUE;
return NULL;
}
}
- DWORD cnt = 1;
- size = 16384; /* As documented in MSDN. */
- nro = (NETRESOURCE *) alloca (size);
- ret = WNetEnumResource (dir->__handle, &cnt, nro, &size);
+ ret = create_thread_and_wait (GET_RESOURCE_ENUM, dir->__handle,
+ nro = (LPNETRESOURCE) alloca (16384),
+ 16384, "WnetEnumResource");
if (ret != NO_ERROR)
{
if (ret != ERROR_NO_MORE_ITEMS)
- __seterrno ();
+ __seterrno_from_win_error (ret);
return NULL;
}
dir->__d_position++;
@@ -163,6 +220,15 @@ fhandler_netdrive::seekdir (DIR *, _off64_t)
{
}
+void
+fhandler_netdrive::rewinddir (DIR *dir)
+{
+ if (dir->__handle != INVALID_HANDLE_VALUE)
+ WNetCloseEnum (dir->__handle);
+ dir->__handle = INVALID_HANDLE_VALUE;
+ return fhandler_virtual::rewinddir (dir);
+}
+
int
fhandler_netdrive::closedir (DIR *dir)
{