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

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDick Porter <dick@acm.org>2004-09-24 21:01:37 +0400
committerDick Porter <dick@acm.org>2004-09-24 21:01:37 +0400
commit06aeb1a94e36548f2b5f42a0ecfc9b0fd10ae207 (patch)
treedad7de3590dc4eb648d504e8d09248a92bc5eea7
parent8f2b56a6a0f6991dc60e369837b66307adfc5f93 (diff)
2004-09-24 Dick Porter <dick@ximian.com>
* wapi-private.h: * sockets.c: * socket-private.h: * io.c: * io-private.h: * handles-private.h: Cope when a file descriptor is reused while the handle that thought it owned it is still referenced, instead of asserting. Probably fixes bug 66479, though we've been unable to reproduce it. svn path=/branches/mono-1-0/mono/; revision=34365
-rw-r--r--mono/io-layer/ChangeLog12
-rw-r--r--mono/io-layer/handles-private.h102
-rw-r--r--mono/io-layer/io-private.h6
-rw-r--r--mono/io-layer/io.c287
-rw-r--r--mono/io-layer/socket-private.h2
-rw-r--r--mono/io-layer/sockets.c40
-rw-r--r--mono/io-layer/wapi-private.h13
7 files changed, 304 insertions, 158 deletions
diff --git a/mono/io-layer/ChangeLog b/mono/io-layer/ChangeLog
index 884514fe184..1e8396bbe26 100644
--- a/mono/io-layer/ChangeLog
+++ b/mono/io-layer/ChangeLog
@@ -1,3 +1,15 @@
+2004-09-24 Dick Porter <dick@ximian.com>
+
+ * wapi-private.h:
+ * sockets.c:
+ * socket-private.h:
+ * io.c:
+ * io-private.h:
+ * handles-private.h: Cope when a file descriptor is reused while
+ the handle that thought it owned it is still referenced, instead
+ of asserting. Probably fixes bug 66479, though we've been unable
+ to reproduce it.
+
2004-09-09 Dick Porter <dick@ximian.com>
* error.c:
diff --git a/mono/io-layer/handles-private.h b/mono/io-layer/handles-private.h
index 36890a97160..ad03546705c 100644
--- a/mono/io-layer/handles-private.h
+++ b/mono/io-layer/handles-private.h
@@ -96,43 +96,6 @@ extern gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode,
extern void _wapi_handle_set_share (dev_t device, ino_t inode,
guint32 sharemode, guint32 access);
-static inline void _wapi_handle_fd_offset_store (int fd, gpointer handle)
-{
- g_assert (fd < _wapi_fd_offset_table_size);
- g_assert (_wapi_fd_offset_table[fd]==NULL || handle==NULL);
- g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size || handle==NULL);
-
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Assigning fd offset %d to %p", fd,
- handle);
-#endif
-
- _wapi_fd_offset_table[fd]=handle;
-}
-
-static inline gpointer _wapi_handle_fd_offset_to_handle (gpointer fd_handle)
-{
- int fd = GPOINTER_TO_INT (fd_handle);
- gpointer handle;
-
- if (fd >= _wapi_fd_offset_table_size) {
- return(NULL);
- }
-
- handle = _wapi_fd_offset_table[fd];
-
- if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
- return(NULL);
- }
-
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Returning fd offset %d of %p", fd,
- handle);
-#endif
-
- return(handle);
-}
-
static inline struct _WapiHandleShared_list *_wapi_handle_get_shared_segment (guint32 segment)
{
struct _WapiHandleShared_list *shared;
@@ -260,6 +223,29 @@ static inline guint32 _wapi_handle_index (guint32 segment, guint32 idx)
return((segment*_WAPI_HANDLES_PER_SEGMENT)+idx);
}
+static inline gpointer _wapi_handle_fd_offset_to_handle (gpointer fd_handle)
+{
+ int fd = GPOINTER_TO_INT (fd_handle);
+ gpointer handle;
+
+ if (fd >= _wapi_fd_offset_table_size) {
+ return(NULL);
+ }
+
+ handle = _wapi_fd_offset_table[fd];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ return(NULL);
+ }
+
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Returning fd offset %d of %p", fd,
+ handle);
+#endif
+
+ return(handle);
+}
+
static inline WapiHandleType _wapi_handle_type (gpointer handle)
{
guint32 idx;
@@ -277,6 +263,48 @@ static inline WapiHandleType _wapi_handle_type (gpointer handle)
return(_wapi_handle_get_shared_segment (segment)->handles[idx].type);
}
+static inline void _wapi_handle_fd_offset_store (int fd, gpointer handle)
+{
+ g_assert (fd < _wapi_fd_offset_table_size);
+
+ if (_wapi_fd_offset_table[fd] != NULL && handle != NULL) {
+ gpointer oldhandle = _wapi_fd_offset_table[fd];
+ struct _WapiHandlePrivate *private_handle;
+ guint32 idx;
+ guint32 segment;
+
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION
+ ": Reassigning fd offset %d from %p", fd,
+ oldhandle);
+#endif
+
+ /* The WapiFDMapped struct at the head of the private
+ * handle data means we don't need to do a full
+ * lookup, and we don't need to know the handle type.
+ */
+ g_assert (_wapi_handle_type (oldhandle) == WAPI_HANDLE_FILE ||
+ _wapi_handle_type (oldhandle) == WAPI_HANDLE_CONSOLE ||
+ _wapi_handle_type (oldhandle) == WAPI_HANDLE_PIPE ||
+ _wapi_handle_type (oldhandle) == WAPI_HANDLE_SOCKET);
+
+ _wapi_handle_segment (oldhandle, &segment, &idx);
+ _wapi_handle_ensure_mapped (segment);
+
+ private_handle=&_wapi_handle_get_private_segment(segment)->handles[idx];
+ ((WapiFDMapped *)(&private_handle->u))->assigned = FALSE;
+ }
+
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size || handle==NULL);
+
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Assigning fd offset %d to %p", fd,
+ handle);
+#endif
+
+ _wapi_fd_offset_table[fd]=handle;
+}
+
static inline void _wapi_handle_set_signal_state (gpointer handle,
gboolean state,
gboolean broadcast)
diff --git a/mono/io-layer/io-private.h b/mono/io-layer/io-private.h
index 374be059956..0fd2b4a7d4b 100644
--- a/mono/io-layer/io-private.h
+++ b/mono/io-layer/io-private.h
@@ -34,13 +34,9 @@ struct _WapiHandle_file
ino_t inode;
};
-/* The boolean is for distinguishing between a zeroed struct being not
- * as yet assigned, and one containing a valid fd 0
- */
struct _WapiHandlePrivate_file
{
- int fd;
- gboolean assigned;
+ WapiFDMapped fd_mapped;
gboolean async;
WapiOverlappedCB callback;
};
diff --git a/mono/io-layer/io.c b/mono/io-layer/io.c
index 6a326e51763..d7434e99a7b 100644
--- a/mono/io-layer/io.c
+++ b/mono/io-layer/io.c
@@ -268,15 +268,17 @@ static void file_close_private (gpointer handle)
return;
}
+ if (file_private_handle->fd_mapped.assigned) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing file handle %p with fd %d",
- handle, file_private_handle->fd);
+ g_message(G_GNUC_PRETTY_FUNCTION ": closing file handle %p with fd %d",
+ handle, file_private_handle->fd_mapped.fd);
#endif
- /* Blank out the mapping, to make catching errors easier */
- _wapi_handle_fd_offset_store (file_private_handle->fd, NULL);
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (file_private_handle->fd_mapped.fd, NULL);
- close(file_private_handle->fd);
+ close(file_private_handle->fd_mapped.fd);
+ }
}
static WapiFileType file_getfiletype(void)
@@ -334,6 +336,11 @@ static gboolean file_read(gpointer handle, gpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(bytesread!=NULL) {
*bytesread=0;
@@ -342,7 +349,7 @@ static gboolean file_read(gpointer handle, gpointer buffer,
if(!(file_handle->fileaccess&GENERIC_READ) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -351,7 +358,8 @@ static gboolean file_read(gpointer handle, gpointer buffer,
if (file_private_handle->async == FALSE) {
do {
- ret=read(file_private_handle->fd, buffer, numbytes);
+ ret=read(file_private_handle->fd_mapped.fd, buffer,
+ numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -361,7 +369,8 @@ static gboolean file_read(gpointer handle, gpointer buffer,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": read of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(err));
+ file_private_handle->fd_mapped.fd,
+ strerror(err));
#endif
SetLastError (_wapi_get_win32_file_error (err));
return(FALSE);
@@ -384,7 +393,7 @@ static gboolean file_read(gpointer handle, gpointer buffer,
}
{
- int fd = file_private_handle->fd;
+ int fd = file_private_handle->fd_mapped.fd;
struct aiocb *aio;
int result;
notifier_data_t *ndata;
@@ -451,6 +460,11 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(byteswritten!=NULL) {
*byteswritten=0;
@@ -459,7 +473,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
if(!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -473,35 +487,37 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
* because we only do advisory locking on POSIX
* systems
*/
- current_pos = lseek (file_private_handle->fd, (off_t)0,
- SEEK_CUR);
+ current_pos = lseek (file_private_handle->fd_mapped.fd,
+ (off_t)0, SEEK_CUR);
if (current_pos == -1) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d lseek failed: %s", handle, file_private_handle->fd, strerror (errno));
+ g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d lseek failed: %s", handle, file_private_handle->fd_mapped.fd, strerror (errno));
#endif
_wapi_set_last_error_from_errno ();
return(FALSE);
}
- if (_wapi_lock_file_region (file_private_handle->fd,
+ if (_wapi_lock_file_region (file_private_handle->fd_mapped.fd,
current_pos, numbytes) == FALSE) {
/* The error has already been set */
return(FALSE);
}
do {
- ret=write(file_private_handle->fd, buffer, numbytes);
+ ret=write(file_private_handle->fd_mapped.fd, buffer,
+ numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
- _wapi_unlock_file_region (file_private_handle->fd, current_pos,
- numbytes);
+ _wapi_unlock_file_region (file_private_handle->fd_mapped.fd,
+ current_pos, numbytes);
if(ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": write of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd,
+ strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -523,7 +539,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
}
{
- int fd = file_private_handle->fd;
+ int fd = file_private_handle->fd_mapped.fd;
struct aiocb *aio;
int result;
notifier_data_t *ndata;
@@ -589,22 +605,27 @@ static gboolean file_flush(gpointer handle)
return(FALSE);
}
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
if(!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- ret=fsync(file_private_handle->fd);
+ ret=fsync(file_private_handle->fd_mapped.fd);
if (ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": fsync of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -633,12 +654,17 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_SET_FILE_POINTER);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(!(file_handle->fileaccess&GENERIC_READ) &&
!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -688,20 +714,21 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
#ifdef HAVE_LARGE_FILE_SUPPORT
g_message(G_GNUC_PRETTY_FUNCTION
": moving handle %p fd %d by %lld bytes from %d", handle,
- file_private_handle->fd, offset, whence);
+ file_private_handle->fd_mapped.fd, offset, whence);
#else
g_message(G_GNUC_PRETTY_FUNCTION
": moving handle %p fd %d by %ld bytes from %d", handle,
- file_private_handle->fd, offset, whence);
+ file_private_handle->fd_mapped.fd, offset, whence);
#endif
#endif
- newpos=lseek(file_private_handle->fd, offset, whence);
+ newpos=lseek(file_private_handle->fd_mapped.fd, offset, whence);
if(newpos==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": lseek on handle %p fd %d returned error %s",
- handle, file_private_handle->fd, strerror(errno));
+ handle, file_private_handle->fd_mapped.fd,
+ strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -732,7 +759,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": move of handle %p fd %d returning %d/%d", handle,
- file_private_handle->fd, ret,
+ file_private_handle->fd_mapped.fd, ret,
highmovedistance==NULL?0:*highmovedistance);
#endif
@@ -757,11 +784,16 @@ static gboolean file_setendoffile(gpointer handle)
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -774,12 +806,12 @@ static gboolean file_setendoffile(gpointer handle)
* than the length, truncate the file.
*/
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(file_private_handle->fd_mapped.fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -787,12 +819,12 @@ static gboolean file_setendoffile(gpointer handle)
}
size=statbuf.st_size;
- pos=lseek(file_private_handle->fd, (off_t)0, SEEK_CUR);
+ pos=lseek(file_private_handle->fd_mapped.fd, (off_t)0, SEEK_CUR);
if(pos==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d lseek failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -802,7 +834,7 @@ static gboolean file_setendoffile(gpointer handle)
if(pos>size) {
/* extend */
do {
- ret=write(file_private_handle->fd, "", 1);
+ ret=write(file_private_handle->fd_mapped.fd, "", 1);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -810,7 +842,7 @@ static gboolean file_setendoffile(gpointer handle)
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d extend write failed: %s",
- handle, file_private_handle->fd,
+ handle, file_private_handle->fd_mapped.fd,
strerror(errno));
#endif
@@ -823,7 +855,7 @@ static gboolean file_setendoffile(gpointer handle)
* byte to the end of the file
*/
do {
- ret=ftruncate(file_private_handle->fd, pos);
+ ret=ftruncate(file_private_handle->fd_mapped.fd, pos);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -831,7 +863,7 @@ static gboolean file_setendoffile(gpointer handle)
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d ftruncate failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -859,24 +891,29 @@ static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_FILE_SIZE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(!(file_handle->fileaccess&GENERIC_READ) &&
!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(INVALID_FILE_SIZE);
}
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(file_private_handle->fd_mapped.fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -924,23 +961,28 @@ static gboolean file_getfiletime(gpointer handle, WapiFileTime *create_time,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(!(file_handle->fileaccess&GENERIC_READ) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(file_private_handle->fd_mapped.fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -1018,11 +1060,16 @@ static gboolean file_setfiletime(gpointer handle,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(!(file_handle->fileaccess&GENERIC_WRITE) &&
!(file_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -1033,7 +1080,7 @@ static gboolean file_setfiletime(gpointer handle,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d unknown filename", handle,
- file_private_handle->fd);
+ file_private_handle->fd_mapped.fd);
#endif
SetLastError (ERROR_INVALID_HANDLE);
@@ -1043,12 +1090,12 @@ static gboolean file_setfiletime(gpointer handle,
/* Get the current times, so we can put the same times back in
* the event that one of the FileTime structs is NULL
*/
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(file_private_handle->fd_mapped.fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ file_private_handle->fd_mapped.fd, strerror(errno));
#endif
SetLastError (ERROR_INVALID_PARAMETER);
@@ -1108,7 +1155,8 @@ static gboolean file_setfiletime(gpointer handle,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": handle %p [%s] fd %d utime failed: %s", handle,
- name, file_private_handle->fd, strerror(errno));
+ name, file_private_handle->fd_mapped.fd,
+ strerror(errno));
#endif
g_free (name);
@@ -1163,16 +1211,18 @@ static void console_close_private (gpointer handle)
return;
}
+ if (console_private_handle->fd_mapped.assigned == TRUE) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": closing console handle %p with fd %d", handle,
- console_private_handle->fd);
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": closing console handle %p with fd %d", handle,
+ console_private_handle->fd_mapped.fd);
#endif
- /* Blank out the mapping, to make catching errors easier */
- _wapi_handle_fd_offset_store (console_private_handle->fd, NULL);
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (console_private_handle->fd_mapped.fd, NULL);
- close(console_private_handle->fd);
+ close(console_private_handle->fd_mapped.fd);
+ }
}
static WapiFileType console_getfiletype(void)
@@ -1198,6 +1248,11 @@ static gboolean console_read(gpointer handle, gpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (console_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(bytesread!=NULL) {
*bytesread=0;
@@ -1206,7 +1261,7 @@ static gboolean console_read(gpointer handle, gpointer buffer,
if(!(console_handle->fileaccess&GENERIC_READ) &&
!(console_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, console_private_handle->fd_mapped.fd, console_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -1214,7 +1269,8 @@ static gboolean console_read(gpointer handle, gpointer buffer,
}
do {
- ret=read(console_private_handle->fd, buffer, numbytes);
+ ret=read(console_private_handle->fd_mapped.fd, buffer,
+ numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -1222,7 +1278,8 @@ static gboolean console_read(gpointer handle, gpointer buffer,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": read of handle %p fd %d error: %s", handle,
- console_private_handle->fd, strerror(errno));
+ console_private_handle->fd_mapped.fd,
+ strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -1254,6 +1311,11 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (console_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(byteswritten!=NULL) {
*byteswritten=0;
@@ -1262,7 +1324,7 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
if(!(console_handle->fileaccess&GENERIC_WRITE) &&
!(console_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, console_private_handle->fd_mapped.fd, console_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -1270,7 +1332,8 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
}
do {
- ret=write(console_private_handle->fd, buffer, numbytes);
+ ret=write(console_private_handle->fd_mapped.fd, buffer,
+ numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -1278,7 +1341,8 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": write of handle %p fd %d error: %s", handle,
- console_private_handle->fd, strerror(errno));
+ console_private_handle->fd_mapped.fd,
+ strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -1333,16 +1397,18 @@ static void pipe_close_private (gpointer handle)
return;
}
+ if (pipe_private_handle->fd_mapped.fd == TRUE) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": closing pipe handle %p with fd %d", handle,
- pipe_private_handle->fd);
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": closing pipe handle %p with fd %d", handle,
+ pipe_private_handle->fd_mapped.fd);
#endif
- /* Blank out the mapping, to make catching errors easier */
- _wapi_handle_fd_offset_store (pipe_private_handle->fd, NULL);
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (pipe_private_handle->fd_mapped.fd, NULL);
- close(pipe_private_handle->fd);
+ close(pipe_private_handle->fd_mapped.fd);
+ }
}
static WapiFileType pipe_getfiletype(void)
@@ -1368,7 +1434,12 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
+
+ if (pipe_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
if(bytesread!=NULL) {
*bytesread=0;
}
@@ -1376,7 +1447,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
if(!(pipe_handle->fileaccess&GENERIC_READ) &&
!(pipe_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, pipe_private_handle->fd_mapped.fd, pipe_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -1386,11 +1457,11 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": reading up to %d bytes from pipe %p (fd %d)", numbytes,
- handle, pipe_private_handle->fd);
+ handle, pipe_private_handle->fd_mapped.fd);
#endif
do {
- ret=read(pipe_private_handle->fd, buffer, numbytes);
+ ret=read(pipe_private_handle->fd_mapped.fd, buffer, numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -1398,7 +1469,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": read of handle %p fd %d error: %s", handle,
- pipe_private_handle->fd, strerror(errno));
+ pipe_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -1434,6 +1505,11 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
+
+ if (pipe_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
if(byteswritten!=NULL) {
*byteswritten=0;
@@ -1442,7 +1518,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
if(!(pipe_handle->fileaccess&GENERIC_WRITE) &&
!(pipe_handle->fileaccess&GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
+ g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, pipe_private_handle->fd_mapped.fd, pipe_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
@@ -1452,11 +1528,11 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": writing up to %d bytes to pipe %p (fd %d)", numbytes,
- handle, pipe_private_handle->fd);
+ handle, pipe_private_handle->fd_mapped.fd);
#endif
do {
- ret=write(pipe_private_handle->fd, buffer, numbytes);
+ ret=write(pipe_private_handle->fd_mapped.fd, buffer, numbytes);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -1464,7 +1540,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": write of handle %p fd %d error: %s", handle,
- pipe_private_handle->fd, strerror(errno));
+ pipe_private_handle->fd_mapped.fd, strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
@@ -1773,8 +1849,8 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
_wapi_handle_fd_offset_store (fd, handle);
cf_ret = GINT_TO_POINTER (fd);
- file_private_handle->fd=fd;
- file_private_handle->assigned=TRUE;
+ file_private_handle->fd_mapped.fd=fd;
+ file_private_handle->fd_mapped.assigned=TRUE;
file_private_handle->async = ((attrs & FILE_FLAG_OVERLAPPED) != 0);
file_handle->filename=_wapi_handle_scratch_store (filename,
strlen (filename));
@@ -1792,7 +1868,7 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": returning handle %p with fd %d", handle,
- file_private_handle->fd);
+ file_private_handle->fd_mapped.fd);
#endif
cleanup:
@@ -2164,8 +2240,8 @@ static gpointer stdhandle_create (int fd, const guchar *name)
_wapi_handle_fd_offset_store (fd, handle);
ret = GINT_TO_POINTER (fd);
- file_private_handle->fd=fd;
- file_private_handle->assigned=TRUE;
+ file_private_handle->fd_mapped.fd=fd;
+ file_private_handle->fd_mapped.assigned=TRUE;
file_handle->filename=_wapi_handle_scratch_store (name, strlen (name));
/* some default security attributes might be needed */
file_handle->security_attributes=0;
@@ -2175,7 +2251,7 @@ static gpointer stdhandle_create (int fd, const guchar *name)
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION ": returning handle %p with fd %d",
- handle, file_private_handle->fd);
+ handle, file_private_handle->fd_mapped.fd);
#endif
cleanup:
@@ -3695,14 +3771,19 @@ int _wapi_file_handle_to_fd (gpointer fd_handle)
}
}
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(-1);
+ }
+
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": returning %d",
- file_private_handle->fd);
+ file_private_handle->fd_mapped.fd);
#endif
- g_assert (file_private_handle->fd == GPOINTER_TO_INT (fd_handle));
+ g_assert (file_private_handle->fd_mapped.fd == GPOINTER_TO_INT (fd_handle));
- return(file_private_handle->fd);
+ return(file_private_handle->fd_mapped.fd);
}
gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
@@ -3814,15 +3895,15 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
}
cp_ret = TRUE;
- pipe_read_private_handle->fd=filedes[0];
- pipe_read_private_handle->assigned=TRUE;
+ pipe_read_private_handle->fd_mapped.fd=filedes[0];
+ pipe_read_private_handle->fd_mapped.assigned=TRUE;
pipe_read_handle->fileaccess=GENERIC_READ;
_wapi_handle_fd_offset_store (filedes[0], read_handle);
*readpipe=GINT_TO_POINTER (filedes[0]);
- pipe_write_private_handle->fd=filedes[1];
- pipe_write_private_handle->assigned=TRUE;
+ pipe_write_private_handle->fd_mapped.fd=filedes[1];
+ pipe_write_private_handle->fd_mapped.assigned=TRUE;
pipe_write_handle->fileaccess=GENERIC_WRITE;
_wapi_handle_fd_offset_store (filedes[1], write_handle);
@@ -4114,11 +4195,16 @@ gboolean LockFile (gpointer fd_handle, guint32 offset_low, guint32 offset_high,
return(FALSE);
}
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
if (!(file_handle->fileaccess & GENERIC_READ) &&
!(file_handle->fileaccess & GENERIC_WRITE) &&
!(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
@@ -4131,7 +4217,7 @@ gboolean LockFile (gpointer fd_handle, guint32 offset_low, guint32 offset_high,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": Locking handle %p fd %d, offset %lld, length %lld",
- handle, file_private_handle->fd, offset, length);
+ handle, file_private_handle->fd_mapped.fd, offset, length);
#endif
#else
offset = offset_low;
@@ -4140,12 +4226,12 @@ gboolean LockFile (gpointer fd_handle, guint32 offset_low, guint32 offset_high,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": Locking handle %p fd %d, offset %ld, length %ld",
- handle, file_private_handle->fd, offset, length);
+ handle, file_private_handle->fd_mapped.fd, offset, length);
#endif
#endif
- return(_wapi_lock_file_region (file_private_handle->fd, offset,
- length));
+ return(_wapi_lock_file_region (file_private_handle->fd_mapped.fd,
+ offset, length));
}
gboolean UnlockFile (gpointer fd_handle, guint32 offset_low,
@@ -4173,11 +4259,16 @@ gboolean UnlockFile (gpointer fd_handle, guint32 offset_low,
return(FALSE);
}
+ if (file_private_handle->fd_mapped.assigned == FALSE) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
if (!(file_handle->fileaccess & GENERIC_READ) &&
!(file_handle->fileaccess & GENERIC_WRITE) &&
!(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd_mapped.fd, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
@@ -4190,7 +4281,7 @@ gboolean UnlockFile (gpointer fd_handle, guint32 offset_low,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": Unlocking handle %p fd %d, offset %lld, length %lld",
- handle, file_private_handle->fd, offset, length);
+ handle, file_private_handle->fd_mapped.fd, offset, length);
#endif
#else
offset = offset_low;
@@ -4199,10 +4290,10 @@ gboolean UnlockFile (gpointer fd_handle, guint32 offset_low,
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
": Unlocking handle %p fd %d, offset %ld, length %ld",
- handle, file_private_handle->fd, offset, length);
+ handle, file_private_handle->fd_mapped.fd, offset, length);
#endif
#endif
- return(_wapi_unlock_file_region (file_private_handle->fd, offset,
- length));
+ return(_wapi_unlock_file_region (file_private_handle->fd_mapped.fd,
+ offset, length));
}
diff --git a/mono/io-layer/socket-private.h b/mono/io-layer/socket-private.h
index 47f14c1315f..4da7f58d8ad 100644
--- a/mono/io-layer/socket-private.h
+++ b/mono/io-layer/socket-private.h
@@ -22,7 +22,7 @@ struct _WapiHandle_socket
struct _WapiHandlePrivate_socket
{
- int fd;
+ WapiFDMapped fd_mapped;
};
#endif /* _WAPI_SOCKET_PRIVATE_H_ */
diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c
index 25f165763ea..df7ac8a25dc 100644
--- a/mono/io-layer/sockets.c
+++ b/mono/io-layer/sockets.c
@@ -97,24 +97,28 @@ static void socket_close_private (gpointer handle)
g_ptr_array_remove_fast(sockets, GUINT_TO_POINTER (handle));
- /* Blank out the mapping, to make catching errors easier */
- _wapi_handle_fd_offset_store (socket_private_handle->fd, NULL);
+ if (socket_private_handle->fd_mapped.assigned == TRUE) {
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (socket_private_handle->fd_mapped.fd, NULL);
- do {
- ret=close(socket_private_handle->fd);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ do {
+ ret=close(socket_private_handle->fd_mapped.fd);
+ }
+ while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
- if(ret==-1) {
- gint errnum = errno;
+ if(ret==-1) {
+ gint errnum = errno;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": close error: %s",
- strerror(errno));
+ g_message(G_GNUC_PRETTY_FUNCTION ": close error: %s",
+ strerror(errno));
#endif
- errnum = errno_to_WSA (errnum, G_GNUC_PRETTY_FUNCTION);
- WSASetLastError (errnum);
+ errnum = errno_to_WSA (errnum, G_GNUC_PRETTY_FUNCTION);
+ WSASetLastError (errnum);
- return;
+ return;
+ }
+ } else {
+ WSASetLastError(WSAENOTSOCK);
}
}
@@ -298,12 +302,13 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
_wapi_handle_fd_offset_store (new_fd, new_handle);
ret = new_fd;
- new_socket_private_handle->fd=new_fd;
+ new_socket_private_handle->fd_mapped.fd = new_fd;
+ new_socket_private_handle->fd_mapped.assigned = TRUE;
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": returning newly accepted socket handle %p with fd %d",
- new_handle, new_socket_private_handle->fd);
+ new_handle, new_socket_private_handle->fd_mapped.fd);
#endif
cleanup:
@@ -814,12 +819,13 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused, guint32 u
_wapi_handle_fd_offset_store (fd, handle);
ret = fd;
- socket_private_handle->fd=fd;
+ socket_private_handle->fd_mapped.fd = fd;
+ socket_private_handle->fd_mapped.assigned = TRUE;
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
": returning socket handle %p with fd %d", handle,
- socket_private_handle->fd);
+ socket_private_handle->fd_mapped.fd);
#endif
cleanup:
diff --git a/mono/io-layer/wapi-private.h b/mono/io-layer/wapi-private.h
index 92e0682288a..2a7203c6937 100644
--- a/mono/io-layer/wapi-private.h
+++ b/mono/io-layer/wapi-private.h
@@ -59,6 +59,19 @@ typedef struct
guint32 name;
} WapiSharedNamespace;
+/* The boolean is for distinguishing between a zeroed struct being not
+ * as yet assigned, and one containing a valid fd 0. It's also used
+ * to signal that a previously-good fd has been reused behind our
+ * back, so we need to invalidate the handle that thought it owned the
+ * fd.
+ */
+typedef struct
+{
+ int fd;
+ gboolean assigned;
+} WapiFDMapped;
+
+
typedef enum {
WAPI_HANDLE_CAP_WAIT=0x01,
WAPI_HANDLE_CAP_SIGNAL=0x02,