#region DuplicateAndClose
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern bool Duplicate_internal(IntPtr handle, int targetProcessId, out IntPtr duplicateHandle, out MonoIOError error);
+
[MonoLimitation ("We do not support passing sockets across processes, we merely allow this API to pass the socket across AppDomains")]
public SocketInformation DuplicateAndClose (int targetProcessId)
{
(is_blocking ? 0 : SocketInformationOptions.NonBlocking) |
(useOverlappedIO ? SocketInformationOptions.UseOnlyOverlappedIO : 0);
- MonoIOError error;
IntPtr duplicateHandle;
- if (!MonoIO.DuplicateHandle (System.Diagnostics.Process.GetCurrentProcess ().Handle, Handle, new IntPtr (targetProcessId), out duplicateHandle, 0, 0, 0x00000002 /* DUPLICATE_SAME_ACCESS */, out error))
+ if (!Duplicate_internal (Handle, targetProcessId, out duplicateHandle, out MonoIOError error))
throw MonoIO.GetException (error);
si.ProtocolInformation = Mono.DataConverter.Pack ("iiiil", (int)addressFamily, (int)socketType, (int)protocolType, is_bound ? 1 : 0, (long)duplicateHandle);
sre.c \
sre-encode.c \
sre-save.c \
- custom-attrs.c
+ custom-attrs.c \
+ fdhandle.h \
+ fdhandle.c
# These source files have compile time dependencies on GC code
gc_dependent_sources = \
--- /dev/null
+
+#include "fdhandle.h"
+#include "utils/mono-lazy-init.h"
+#include "utils/mono-coop-mutex.h"
+
+static GHashTable *fds;
+static MonoCoopMutex fds_mutex;
+static MonoFDHandleCallback fds_callback[MONO_FDTYPE_COUNT];
+static mono_lazy_init_t fds_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
+
+static const gchar *types_str[] = {
+ "File",
+ "Console",
+ "Pipe",
+ "Socket",
+ NULL
+};
+
+static void
+fds_remove (gpointer data)
+{
+ MonoFDHandle* fdhandle;
+
+ fdhandle = (MonoFDHandle*) data;
+ g_assert (fdhandle);
+
+ g_assert (fds_callback [fdhandle->type].close);
+ fds_callback [fdhandle->type].close (fdhandle);
+
+ mono_refcount_dec (fdhandle);
+}
+
+static void
+initialize (void)
+{
+ fds = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, fds_remove);
+ mono_coop_mutex_init (&fds_mutex);
+}
+
+void
+mono_fdhandle_register (MonoFDType type, MonoFDHandleCallback *callback)
+{
+ mono_lazy_initialize (&fds_init, initialize);
+ memcpy (&fds_callback [type], callback, sizeof (MonoFDHandleCallback));
+}
+
+static void
+fdhandle_destroy (gpointer data)
+{
+ MonoFDHandle* fdhandle;
+
+ fdhandle = (MonoFDHandle*) data;
+ g_assert (fdhandle);
+
+ g_assert (fds_callback [fdhandle->type].destroy);
+ fds_callback [fdhandle->type].destroy (fdhandle);
+}
+
+void
+mono_fdhandle_init (MonoFDHandle *fdhandle, MonoFDType type, gint fd)
+{
+ mono_refcount_init (fdhandle, fdhandle_destroy);
+ fdhandle->type = type;
+ fdhandle->fd = fd;
+}
+
+void
+mono_fdhandle_insert (MonoFDHandle *fdhandle)
+{
+ mono_coop_mutex_lock (&fds_mutex);
+
+ if (g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fdhandle->fd), NULL, NULL))
+ g_error("%s: duplicate %s fd %d", __func__, types_str [fdhandle->type], fdhandle->fd);
+
+ g_hash_table_insert (fds, GINT_TO_POINTER(fdhandle->fd), fdhandle);
+
+ mono_coop_mutex_unlock (&fds_mutex);
+}
+
+gboolean
+mono_fdhandle_try_insert (MonoFDHandle *fdhandle)
+{
+ mono_coop_mutex_lock (&fds_mutex);
+
+ if (g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fdhandle->fd), NULL, NULL)) {
+ /* we raced between 2 invocations of mono_fdhandle_try_insert */
+ mono_coop_mutex_unlock (&fds_mutex);
+
+ return FALSE;
+ }
+
+ g_hash_table_insert (fds, GINT_TO_POINTER(fdhandle->fd), fdhandle);
+
+ mono_coop_mutex_unlock (&fds_mutex);
+
+ return TRUE;
+}
+
+gboolean
+mono_fdhandle_lookup_and_ref (gint fd, MonoFDHandle **fdhandle)
+{
+ mono_coop_mutex_lock (&fds_mutex);
+
+ if (!g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fd), NULL, (gpointer*) fdhandle)) {
+ mono_coop_mutex_unlock (&fds_mutex);
+ return FALSE;
+ }
+
+ mono_refcount_inc (*fdhandle);
+
+ mono_coop_mutex_unlock (&fds_mutex);
+
+ return TRUE;
+}
+
+void
+mono_fdhandle_unref (MonoFDHandle *fdhandle)
+{
+ mono_refcount_dec (fdhandle);
+}
+
+gboolean
+mono_fdhandle_close (gint fd)
+{
+ MonoFDHandle *fdhandle;
+ gboolean removed;
+
+ mono_coop_mutex_lock (&fds_mutex);
+
+ if (!g_hash_table_lookup_extended (fds, GINT_TO_POINTER(fd), NULL, (gpointer*) &fdhandle)) {
+ mono_coop_mutex_unlock (&fds_mutex);
+
+ return FALSE;
+ }
+
+ removed = g_hash_table_remove (fds, GINT_TO_POINTER(fdhandle->fd));
+ g_assert (removed);
+
+ mono_coop_mutex_unlock (&fds_mutex);
+
+ return TRUE;
+}
--- /dev/null
+
+#ifndef __MONO_METADATA_FDHANDLE_H__
+#define __MONO_METADATA_FDHANDLE_H__
+
+#include <config.h>
+#include <glib.h>
+
+#include "utils/refcount.h"
+
+typedef enum {
+ MONO_FDTYPE_FILE,
+ MONO_FDTYPE_CONSOLE,
+ MONO_FDTYPE_PIPE,
+ MONO_FDTYPE_SOCKET,
+ MONO_FDTYPE_COUNT
+} MonoFDType;
+
+typedef struct {
+ MonoRefCount ref;
+ MonoFDType type;
+ gint fd;
+} MonoFDHandle;
+
+typedef struct {
+ void (*close) (MonoFDHandle *fdhandle);
+ void (*destroy) (MonoFDHandle *fdhandle);
+} MonoFDHandleCallback;
+
+void
+mono_fdhandle_register (MonoFDType type, MonoFDHandleCallback *callback);
+
+void
+mono_fdhandle_init (MonoFDHandle *fdhandle, MonoFDType type, gint fd);
+
+void
+mono_fdhandle_insert (MonoFDHandle *fdhandle);
+
+gboolean
+mono_fdhandle_try_insert (MonoFDHandle *fdhandle);
+
+gboolean
+mono_fdhandle_lookup_and_ref (gint fd, MonoFDHandle **fdhandle);
+
+void
+mono_fdhandle_unref (MonoFDHandle *fdhandle);
+
+gboolean
+mono_fdhandle_close (gint fd);
+
+#endif /* __MONO_METADATA_FDHANDLE_H__ */
HANDLES(ICALL(SOCK_4, "Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal))
HANDLES(ICALL(SOCK_5, "Close_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Close_internal))
HANDLES(ICALL(SOCK_6, "Connect_internal(intptr,System.Net.SocketAddress,int&,bool)", ves_icall_System_Net_Sockets_Socket_Connect_internal))
-HANDLES(ICALL (SOCK_6a, "Disconnect_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Disconnect_internal))
+HANDLES(ICALL(SOCK_6a, "Disconnect_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Disconnect_internal))
+HANDLES(ICALL(SOCK_6b, "Duplicate_internal", ves_icall_System_Net_Sockets_Socket_Duplicate_internal))
HANDLES(ICALL(SOCK_7, "GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal))
HANDLES(ICALL(SOCK_8, "GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal))
HANDLES(ICALL(SOCK_21, "IOControl_internal(intptr,int,byte[],byte[],int&)", ves_icall_System_Net_Sockets_Socket_IOControl_internal))
#include "w32file-unix-glob.h"
#include "w32handle.h"
#include "w32error.h"
+#include "fdhandle.h"
#include "utils/mono-io-portability.h"
#include "utils/mono-logger-internals.h"
#include "utils/mono-os-mutex.h"
/* Currently used for both FILE, CONSOLE and PIPE handle types.
* This may have to change in future. */
typedef struct {
+ MonoFDHandle fdhandle;
gchar *filename;
FileShare *share_info; /* Pointer into shared mem */
- gint fd;
guint32 security_attributes;
guint32 fileaccess;
guint32 sharemode;
guint32 attrs;
-} MonoW32HandleFile;
+} FileHandle;
typedef struct {
gchar **namelist;
filetime->dwHighDateTime = ticks >> 32;
}
+static FileHandle*
+file_data_create (MonoFDType type, gint fd)
+{
+ FileHandle *filehandle;
+
+ filehandle = g_new0 (FileHandle, 1);
+ mono_fdhandle_init ((MonoFDHandle*) filehandle, type, fd);
+
+ return filehandle;
+}
+
+static gint
+_wapi_unlink (const gchar *pathname);
+
+static void
+file_share_release (FileShare *share_info);
+
+static void
+file_data_close (MonoFDHandle *fdhandle)
+{
+ FileHandle* filehandle;
+
+ filehandle = (FileHandle*) fdhandle;
+ g_assert (filehandle);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing fd %d", __func__, ((MonoFDHandle*) filehandle)->fd);
+
+ if (((MonoFDHandle*) filehandle)->type == MONO_FDTYPE_FILE && (filehandle->attrs & FILE_FLAG_DELETE_ON_CLOSE)) {
+ _wapi_unlink (filehandle->filename);
+ }
+
+ if (((MonoFDHandle*) filehandle)->type != MONO_FDTYPE_CONSOLE || ((MonoFDHandle*) filehandle)->fd > 2) {
+ if (filehandle->share_info) {
+ file_share_release (filehandle->share_info);
+ filehandle->share_info = NULL;
+ }
+
+ MONO_ENTER_GC_SAFE;
+ close (((MonoFDHandle*) filehandle)->fd);
+ MONO_EXIT_GC_SAFE;
+ }
+}
+
+static void
+file_data_destroy (MonoFDHandle *fdhandle)
+{
+ FileHandle *filehandle;
+
+ filehandle = (FileHandle*) fdhandle;
+ g_assert (filehandle);
+
+ if (filehandle->filename)
+ g_free (filehandle->filename);
+
+ g_free (filehandle);
+}
+
static void
file_share_release (FileShare *share_info)
{
g_assert (share_info->handle_refs > 0);
share_info->handle_refs -= 1;
- if (share_info->handle_refs == 0)
+ if (share_info->handle_refs == 0) {
g_hash_table_remove (file_share_table, share_info);
+ // g_free (share_info);
+ }
mono_coop_mutex_unlock (&file_share_mutex);
}
return TRUE;
}
-static void file_close (gpointer handle, gpointer data);
-static void file_details (gpointer data);
-static const gchar* file_typename (void);
-static gsize file_typesize (void);
-static gint file_getfiletype(void);
-static gboolean file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread);
-static gboolean file_write(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten);
-static gboolean file_flush(gpointer handle);
-static guint32 file_seek(gpointer handle, gint32 movedistance,
- gint32 *highmovedistance, gint method);
-static gboolean file_setendoffile(gpointer handle);
-static guint32 file_getfilesize(gpointer handle, guint32 *highsize);
-static gboolean file_getfiletime(gpointer handle, FILETIME *create_time,
- FILETIME *access_time,
- FILETIME *write_time);
-static gboolean file_setfiletime(gpointer handle,
- const FILETIME *create_time,
- const FILETIME *access_time,
- const FILETIME *write_time);
-static guint32 GetDriveTypeFromPath (const gchar *utf8_root_path_name);
-
-/* File handle is only signalled for overlapped IO */
-static MonoW32HandleOps _wapi_file_ops = {
- file_close, /* close */
- NULL, /* signal */
- NULL, /* own */
- NULL, /* is_owned */
- NULL, /* special_wait */
- NULL, /* prewait */
- file_details, /* details */
- file_typename, /* typename */
- file_typesize, /* typesize */
-};
-
-static void console_close (gpointer handle, gpointer data);
-static void console_details (gpointer data);
-static const gchar* console_typename (void);
-static gsize console_typesize (void);
-static gint console_getfiletype(void);
-static gboolean console_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread);
-static gboolean console_write(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten);
-
-/* Console is mostly the same as file, except it can block waiting for
- * input or output
- */
-static MonoW32HandleOps _wapi_console_ops = {
- console_close, /* close */
- NULL, /* signal */
- NULL, /* own */
- NULL, /* is_owned */
- NULL, /* special_wait */
- NULL, /* prewait */
- console_details, /* details */
- console_typename, /* typename */
- console_typesize, /* typesize */
-};
+static const gchar* find_typename (void)
+{
+ return "Find";
+}
-static const gchar* find_typename (void);
-static gsize find_typesize (void);
+static gsize find_typesize (void)
+{
+ return sizeof (MonoW32HandleFind);
+}
static MonoW32HandleOps _wapi_find_ops = {
NULL, /* close */
find_typesize, /* typesize */
};
-static void pipe_close (gpointer handle, gpointer data);
-static void pipe_details (gpointer data);
-static const gchar* pipe_typename (void);
-static gsize pipe_typesize (void);
-static gint pipe_getfiletype (void);
-static gboolean pipe_read (gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread);
-static gboolean pipe_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten);
-
-/* Pipe handles
- */
-static MonoW32HandleOps _wapi_pipe_ops = {
- pipe_close, /* close */
- NULL, /* signal */
- NULL, /* own */
- NULL, /* is_owned */
- NULL, /* special_wait */
- NULL, /* prewait */
- pipe_details, /* details */
- pipe_typename, /* typename */
- pipe_typesize, /* typesize */
-};
-
-static const struct {
- /* File, console and pipe handles */
- gint (*getfiletype)(void);
-
- /* File, console and pipe handles */
- gboolean (*readfile)(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread);
- gboolean (*writefile)(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten);
- gboolean (*flushfile)(gpointer handle);
-
- /* File handles */
- guint32 (*seek)(gpointer handle, gint32 movedistance,
- gint32 *highmovedistance, gint method);
- gboolean (*setendoffile)(gpointer handle);
- guint32 (*getfilesize)(gpointer handle, guint32 *highsize);
- gboolean (*getfiletime)(gpointer handle, FILETIME *create_time,
- FILETIME *access_time,
- FILETIME *write_time);
- gboolean (*setfiletime)(gpointer handle,
- const FILETIME *create_time,
- const FILETIME *access_time,
- const FILETIME *write_time);
-} io_ops[MONO_W32HANDLE_COUNT]={
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* file */
- {file_getfiletype,
- file_read, file_write,
- file_flush, file_seek,
- file_setendoffile,
- file_getfilesize,
- file_getfiletime,
- file_setfiletime},
- /* console */
- {console_getfiletype,
- console_read,
- console_write,
- NULL, NULL, NULL, NULL, NULL, NULL},
- /* thread */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* sem */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* mutex */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* event */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* socket (will need at least read and write) */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* find */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* process */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
- /* pipe */
- {pipe_getfiletype,
- pipe_read,
- pipe_write,
- NULL, NULL, NULL, NULL, NULL, NULL},
-};
-
static gboolean lock_while_writing = FALSE;
/* Some utility functions.
}
}
-/* Handle ops.
- */
-static void file_close (gpointer handle, gpointer data)
-{
- /* FIXME: after mono_w32handle_close is coop-aware, change this to MONO_REQ_GC_UNSAFE_MODE and leave just the switch to SAFE around close() below */
- MONO_ENTER_GC_UNSAFE;
- MonoW32HandleFile *file_handle = (MonoW32HandleFile *)data;
- gint fd = file_handle->fd;
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing file handle %p [%s]", __func__, handle,
- file_handle->filename);
-
- if (file_handle->attrs & FILE_FLAG_DELETE_ON_CLOSE)
- _wapi_unlink (file_handle->filename);
-
- g_free (file_handle->filename);
-
- if (file_handle->share_info)
- file_share_release (file_handle->share_info);
-
- MONO_ENTER_GC_SAFE;
- close (fd);
- MONO_EXIT_GC_SAFE;
- MONO_EXIT_GC_UNSAFE;
-}
-
-static void file_details (gpointer data)
-{
- MonoW32HandleFile *file = (MonoW32HandleFile *)data;
-
- g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
- file->filename,
- file->fileaccess&GENERIC_READ?'R':'.',
- file->fileaccess&GENERIC_WRITE?'W':'.',
- file->fileaccess&GENERIC_EXECUTE?'X':'.',
- file->sharemode&FILE_SHARE_READ?'R':'.',
- file->sharemode&FILE_SHARE_WRITE?'W':'.',
- file->sharemode&FILE_SHARE_DELETE?'D':'.',
- file->attrs);
-}
-
-static const gchar* file_typename (void)
-{
- return "File";
-}
-
-static gsize file_typesize (void)
-{
- return sizeof (MonoW32HandleFile);
-}
-
-static gint file_getfiletype(void)
-{
- return(FILE_TYPE_DISK);
-}
-
static gboolean
-file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
+file_read(FileHandle *filehandle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
- gint fd, ret;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
-
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = file_handle->fd;
if(bytesread!=NULL) {
*bytesread=0;
}
- if(!(file_handle->fileaccess & GENERIC_READ) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ access: %u",
- __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
do {
MONO_ENTER_GC_SAFE;
- ret = read (fd, buffer, numbytes);
+ ret = read (((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
gint err = errno;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of handle %p error: %s", __func__,
- handle, strerror(err));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of fd %d error: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(err));
mono_w32error_set_last (mono_w32error_unix_to_win32 (err));
return(FALSE);
}
}
static gboolean
-file_write(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
+file_write(FileHandle *filehandle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
- gint ret, fd;
+ gint ret;
off_t current_pos = 0;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- fd = file_handle->fd;
-
if(byteswritten!=NULL) {
*byteswritten=0;
}
- if(!(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & GENERIC_WRITE) && !(filehandle->fileaccess & GENERIC_ALL)) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
* systems
*/
MONO_ENTER_GC_SAFE;
- current_pos = lseek (fd, (off_t)0, SEEK_CUR);
+ current_pos = lseek (((MonoFDHandle*) filehandle)->fd, (off_t)0, SEEK_CUR);
MONO_EXIT_GC_SAFE;
if (current_pos == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p lseek failed: %s", __func__,
- handle, strerror (errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d lseek failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror (errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
}
- if (_wapi_lock_file_region (fd, current_pos,
- numbytes) == FALSE) {
+ if (_wapi_lock_file_region (((MonoFDHandle*) filehandle)->fd, current_pos, numbytes) == FALSE) {
/* The error has already been set */
return(FALSE);
}
do {
MONO_ENTER_GC_SAFE;
- ret = write (fd, buffer, numbytes);
+ ret = write (((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
if (lock_while_writing) {
- _wapi_unlock_file_region (fd, current_pos, numbytes);
+ _wapi_unlock_file_region (((MonoFDHandle*) filehandle)->fd, current_pos, numbytes);
}
if (ret == -1) {
} else {
_wapi_set_last_error_from_errno ();
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of handle %p error: %s",
- __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of fd %d error: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
return(FALSE);
}
return(TRUE);
}
-static gboolean file_flush(gpointer handle)
+static gboolean file_flush(FileHandle *filehandle)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
- gint ret, fd;
-
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- fd = file_handle->fd;
+ gint ret;
- if(!(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
MONO_ENTER_GC_SAFE;
- ret=fsync(fd);
+ ret=fsync(((MonoFDHandle*) filehandle)->fd);
MONO_EXIT_GC_SAFE;
if (ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fsync of handle %p error: %s", __func__, handle,
- strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fsync of fd %d error: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
return(TRUE);
}
-static guint32 file_seek(gpointer handle, gint32 movedistance,
+static guint32 file_seek(FileHandle *filehandle, gint32 movedistance,
gint32 *highmovedistance, gint method)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
gint64 offset, newpos;
- gint whence, fd;
+ gint whence;
guint32 ret;
-
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(INVALID_SET_FILE_POINTER);
- }
-
- fd = file_handle->fd;
- if(!(file_handle->fileaccess & GENERIC_READ) &&
- !(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(INVALID_SET_FILE_POINTER);
offset=movedistance;
#endif
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: moving handle %p by %" G_GINT64_FORMAT " bytes from %d", __func__,
- handle, offset, whence);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: moving fd %d by %" G_GINT64_FORMAT " bytes from %d", __func__, ((MonoFDHandle*) filehandle)->fd, offset, whence);
#ifdef PLATFORM_ANDROID
/* bionic doesn't support -D_FILE_OFFSET_BITS=64 */
MONO_ENTER_GC_SAFE;
- newpos=lseek64(fd, offset, whence);
+ newpos=lseek64(((MonoFDHandle*) filehandle)->fd, offset, whence);
MONO_EXIT_GC_SAFE;
#else
MONO_ENTER_GC_SAFE;
- newpos=lseek(fd, offset, whence);
+ newpos=lseek(((MonoFDHandle*) filehandle)->fd, offset, whence);
MONO_EXIT_GC_SAFE;
#endif
if(newpos==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: lseek on handle %p returned error %s",
- __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: lseek on fd %d returned error %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(INVALID_SET_FILE_POINTER);
}
#endif
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: move of handle %p returning %" G_GUINT32_FORMAT "/%" G_GINT32_FORMAT, __func__,
- handle, ret, highmovedistance==NULL?0:*highmovedistance);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: move of fd %d returning %" G_GUINT32_FORMAT "/%" G_GINT32_FORMAT, __func__, ((MonoFDHandle*) filehandle)->fd, ret, highmovedistance==NULL?0:*highmovedistance);
return(ret);
}
-static gboolean file_setendoffile(gpointer handle)
+static gboolean file_setendoffile(FileHandle *filehandle)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
struct stat statbuf;
off_t pos;
- gint ret, fd;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = file_handle->fd;
-
- if(!(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
*/
MONO_ENTER_GC_SAFE;
- ret=fstat(fd, &statbuf);
+ ret=fstat(((MonoFDHandle*) filehandle)->fd, &statbuf);
MONO_EXIT_GC_SAFE;
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p fstat failed: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d fstat failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
}
MONO_ENTER_GC_SAFE;
- pos=lseek(fd, (off_t)0, SEEK_CUR);
+ pos=lseek(((MonoFDHandle*) filehandle)->fd, (off_t)0, SEEK_CUR);
MONO_EXIT_GC_SAFE;
if(pos==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p lseek failed: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d lseek failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
*/
do {
MONO_ENTER_GC_SAFE;
- ret = write (fd, "", 1);
+ ret = write (((MonoFDHandle*) filehandle)->fd, "", 1);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p extend write failed: %s", __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d extend write failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
/* And put the file position back after the write */
MONO_ENTER_GC_SAFE;
- ret = lseek (fd, pos, SEEK_SET);
+ ret = lseek (((MonoFDHandle*) filehandle)->fd, pos, SEEK_SET);
MONO_EXIT_GC_SAFE;
if (ret == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p second lseek failed: %s",
- __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d second lseek failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
*/
do {
MONO_ENTER_GC_SAFE;
- ret=ftruncate(fd, pos);
+ ret=ftruncate(((MonoFDHandle*) filehandle)->fd, pos);
MONO_EXIT_GC_SAFE;
}
while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p ftruncate failed: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d ftruncate failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
return(TRUE);
}
-static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
+static guint32 file_getfilesize(FileHandle *filehandle, guint32 *highsize)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
struct stat statbuf;
guint32 size;
gint ret;
- gint fd;
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(INVALID_FILE_SIZE);
- }
- fd = file_handle->fd;
-
- if(!(file_handle->fileaccess & GENERIC_READ) &&
- !(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(INVALID_FILE_SIZE);
mono_w32error_set_last (ERROR_SUCCESS);
MONO_ENTER_GC_SAFE;
- ret = fstat(fd, &statbuf);
+ ret = fstat(((MonoFDHandle*) filehandle)->fd, &statbuf);
MONO_EXIT_GC_SAFE;
if (ret == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p fstat failed: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d fstat failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(INVALID_FILE_SIZE);
guint64 bigsize;
gint res;
MONO_ENTER_GC_SAFE;
- res = ioctl (fd, BLKGETSIZE64, &bigsize);
+ res = ioctl (((MonoFDHandle*) filehandle)->fd, BLKGETSIZE64, &bigsize);
MONO_EXIT_GC_SAFE;
if (res < 0) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p ioctl BLKGETSIZE64 failed: %s",
- __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d ioctl BLKGETSIZE64 failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(INVALID_FILE_SIZE);
return(size);
}
-static gboolean file_getfiletime(gpointer handle, FILETIME *create_time,
+static gboolean file_getfiletime(FileHandle *filehandle, FILETIME *create_time,
FILETIME *access_time,
FILETIME *write_time)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
struct stat statbuf;
guint64 create_ticks, access_ticks, write_ticks;
- gint ret, fd;
-
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = file_handle->fd;
+ gint ret;
- if(!(file_handle->fileaccess & GENERIC_READ) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ access: %u",
- __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
MONO_ENTER_GC_SAFE;
- ret=fstat(fd, &statbuf);
+ ret=fstat(((MonoFDHandle*) filehandle)->fd, &statbuf);
MONO_EXIT_GC_SAFE;
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p fstat failed: %s", __func__, handle,
- strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d fstat failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
return(TRUE);
}
-static gboolean file_setfiletime(gpointer handle,
+static gboolean file_setfiletime(FileHandle *filehandle,
const FILETIME *create_time G_GNUC_UNUSED,
const FILETIME *access_time,
const FILETIME *write_time)
{
- MonoW32HandleFile *file_handle;
- gboolean ok;
struct utimbuf utbuf;
struct stat statbuf;
guint64 access_ticks, write_ticks;
- gint ret, fd;
+ gint ret;
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
- (gpointer *)&file_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up file handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = file_handle->fd;
- if(!(file_handle->fileaccess & GENERIC_WRITE) &&
- !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
- if(file_handle->filename == NULL) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p unknown filename", __func__, handle);
+ if(filehandle->filename == NULL) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d unknown filename", __func__, ((MonoFDHandle*) filehandle)->fd);
mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
* the event that one of the FileTime structs is NULL
*/
MONO_ENTER_GC_SAFE;
- ret=fstat (fd, &statbuf);
+ ret=fstat (((MonoFDHandle*) filehandle)->fd, &statbuf);
MONO_EXIT_GC_SAFE;
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p fstat failed: %s", __func__, handle,
- strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d fstat failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
utbuf.modtime=statbuf.st_mtime;
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting handle %p access %ld write %ld", __func__,
- handle, utbuf.actime, utbuf.modtime);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting fd %d access %ld write %ld", __func__,
+ ((MonoFDHandle*) filehandle)->fd, utbuf.actime, utbuf.modtime);
- ret = _wapi_utime (file_handle->filename, &utbuf);
+ ret = _wapi_utime (filehandle->filename, &utbuf);
if (ret == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p [%s] utime failed: %s", __func__,
- handle, file_handle->filename, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d [%s] utime failed: %s", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->filename, g_strerror(errno));
mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
return(TRUE);
}
-static void console_close (gpointer handle, gpointer data)
-{
- /* FIXME: after mono_w32handle_close is coop-aware, change this to MONO_REQ_GC_UNSAFE_MODE and leave just the switch to SAFE around close() below */
- MONO_ENTER_GC_UNSAFE;
- MonoW32HandleFile *console_handle = (MonoW32HandleFile *)data;
- gint fd = console_handle->fd;
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing console handle %p", __func__, handle);
-
- g_free (console_handle->filename);
-
- if (fd > 2) {
- if (console_handle->share_info)
- file_share_release (console_handle->share_info);
- MONO_ENTER_GC_SAFE;
- close (fd);
- MONO_EXIT_GC_SAFE;
- }
- MONO_EXIT_GC_UNSAFE;
-}
-
-static void console_details (gpointer data)
-{
- file_details (data);
-}
-
-static const gchar* console_typename (void)
-{
- return "Console";
-}
-
-static gsize console_typesize (void)
-{
- return sizeof (MonoW32HandleFile);
-}
-
-static gint console_getfiletype(void)
-{
- return(FILE_TYPE_CHAR);
-}
-
static gboolean
-console_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
+console_read(FileHandle *filehandle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
{
- MonoW32HandleFile *console_handle;
- gboolean ok;
- gint ret, fd;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
- (gpointer *)&console_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up console handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = console_handle->fd;
-
if(bytesread!=NULL) {
*bytesread=0;
}
- if(!(console_handle->fileaccess & GENERIC_READ) &&
- !(console_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ access: %u",
- __func__, handle, console_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
do {
MONO_ENTER_GC_SAFE;
- ret=read(fd, buffer, numbytes);
+ ret=read(((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of handle %p error: %s", __func__, handle,
- strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of fd %d error: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
_wapi_set_last_error_from_errno ();
return(FALSE);
}
static gboolean
-console_write(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
+console_write(FileHandle *filehandle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
{
- MonoW32HandleFile *console_handle;
- gboolean ok;
- gint ret, fd;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
- (gpointer *)&console_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up console handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = console_handle->fd;
-
if(byteswritten!=NULL) {
*byteswritten=0;
}
- if(!(console_handle->fileaccess & GENERIC_WRITE) &&
- !(console_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, console_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
do {
MONO_ENTER_GC_SAFE;
- ret = write(fd, buffer, numbytes);
+ ret = write(((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
} else {
_wapi_set_last_error_from_errno ();
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of handle %p error: %s",
- __func__, handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of fd %d error: %s", __func__, ((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
return(FALSE);
}
return(TRUE);
}
-static const gchar* find_typename (void)
-{
- return "Find";
-}
-
-static gsize find_typesize (void)
-{
- return sizeof (MonoW32HandleFind);
-}
-
-static void pipe_close (gpointer handle, gpointer data)
-{
- /* FIXME: after mono_w32handle_close is coop-aware, change this to MONO_REQ_GC_UNSAFE_MODE and leave just the switch to SAFE around close() below */
- MONO_ENTER_GC_UNSAFE;
- MonoW32HandleFile *pipe_handle = (MonoW32HandleFile*)data;
- gint fd = pipe_handle->fd;
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing pipe handle %p fd %d", __func__, handle, fd);
-
- /* No filename with pipe handles */
-
- if (pipe_handle->share_info)
- file_share_release (pipe_handle->share_info);
-
- MONO_ENTER_GC_SAFE;
- close (fd);
- MONO_EXIT_GC_SAFE;
- MONO_EXIT_GC_UNSAFE;
-}
-
-static void pipe_details (gpointer data)
-{
- file_details (data);
-}
-
-static const gchar* pipe_typename (void)
-{
- return "Pipe";
-}
-
-static gsize pipe_typesize (void)
-{
- return sizeof (MonoW32HandleFile);
-}
-
-static gint pipe_getfiletype(void)
-{
- return(FILE_TYPE_PIPE);
-}
-
static gboolean
-pipe_read (gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
+pipe_read (FileHandle *filehandle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
{
- MonoW32HandleFile *pipe_handle;
- gboolean ok;
- gint ret, fd;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
- (gpointer *)&pipe_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up pipe handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = pipe_handle->fd;
-
if(bytesread!=NULL) {
*bytesread=0;
}
- if(!(pipe_handle->fileaccess & GENERIC_READ) &&
- !(pipe_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ access: %u",
- __func__, handle, pipe_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_READ | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: reading up to %" G_GUINT32_FORMAT " bytes from pipe %p", __func__,
- numbytes, handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: reading up to %" G_GUINT32_FORMAT " bytes from pipe %d", __func__, numbytes, ((MonoFDHandle*) filehandle)->fd);
do {
MONO_ENTER_GC_SAFE;
- ret=read(fd, buffer, numbytes);
+ ret=read(((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
} else {
_wapi_set_last_error_from_errno ();
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of handle %p error: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of fd %d error: %s", __func__,((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
return(FALSE);
}
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read %d bytes from pipe %p", __func__, ret, handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read %d bytes from pipe %d", __func__, ret, ((MonoFDHandle*) filehandle)->fd);
if(bytesread!=NULL) {
*bytesread=ret;
}
static gboolean
-pipe_write(gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
+pipe_write(FileHandle *filehandle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
{
- MonoW32HandleFile *pipe_handle;
- gboolean ok;
- gint ret, fd;
+ gint ret;
MonoThreadInfo *info = mono_thread_info_current ();
- ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
- (gpointer *)&pipe_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up pipe handle %p", __func__,
- handle);
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- fd = pipe_handle->fd;
-
if(byteswritten!=NULL) {
*byteswritten=0;
}
- if(!(pipe_handle->fileaccess & GENERIC_WRITE) &&
- !(pipe_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, pipe_handle->fileaccess);
+ if(!(filehandle->fileaccess & (GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: writing up to %" G_GUINT32_FORMAT " bytes to pipe %p", __func__,
- numbytes, handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: writing up to %" G_GUINT32_FORMAT " bytes to pipe %d", __func__, numbytes, ((MonoFDHandle*) filehandle)->fd);
do {
MONO_ENTER_GC_SAFE;
- ret = write (fd, buffer, numbytes);
+ ret = write (((MonoFDHandle*) filehandle)->fd, buffer, numbytes);
MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
} else {
_wapi_set_last_error_from_errno ();
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of handle %p error: %s", __func__,
- handle, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write of fd %d error: %s", __func__,((MonoFDHandle*) filehandle)->fd, g_strerror(errno));
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%" PRIx32 ", file has sharing = NONE", __func__, fileaccess);
file_share_release (*share_info);
+ *share_info = NULL;
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%" PRIx32 ", file has sharing: 0x%" PRIx32, __func__, fileaccess, file_existing_share);
file_share_release (*share_info);
+ *share_info = NULL;
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Access mode prevents open: requested share: 0x%" PRIx32 ", file has access: 0x%" PRIx32, __func__, sharemode, file_existing_access);
file_share_release (*share_info);
+ *share_info = NULL;
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%" PRIx32 ", file has sharing = NONE", __func__, (*share_info)->access);
file_share_release (*share_info);
+ *share_info = NULL;
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%" PRIx32 ", file has sharing: 0x%" PRIx32, __func__, (*share_info)->access, file_existing_share);
file_share_release (*share_info);
+ *share_info = NULL;
return(FALSE);
}
gpointer
mono_w32file_create(const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs)
{
- MonoW32HandleFile file_handle = {0};
- gpointer handle;
+ FileHandle *filehandle;
+ MonoFDType type;
gint flags=convert_flags(fileaccess, createmode);
/*mode_t perms=convert_perms(sharemode);*/
/* we don't use sharemode, because that relates to sharing of
mode_t perms=0666;
gchar *filename;
gint fd, ret;
- MonoW32HandleType handle_type;
struct stat statbuf;
if (attrs & FILE_ATTRIBUTE_TEMPORARY)
}
if (fd == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error opening file %s: %s", __func__, filename,
- strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error opening file %s: %s", __func__, filename, g_strerror(errno));
_wapi_set_last_path_error_from_errno (NULL, filename);
g_free (filename);
return(INVALID_HANDLE_VALUE);
}
- if (fd >= mono_w32handle_fd_reserve) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
-
- mono_w32error_set_last (ERROR_TOO_MANY_OPEN_FILES);
-
- MONO_ENTER_GC_SAFE;
- close (fd);
- MONO_EXIT_GC_SAFE;
- g_free (filename);
-
- return(INVALID_HANDLE_VALUE);
- }
-
MONO_ENTER_GC_SAFE;
ret = fstat (fd, &statbuf);
MONO_EXIT_GC_SAFE;
if (ret == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fstat error of file %s: %s", __func__,
- filename, strerror (errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fstat error of file %s: %s", __func__, filename, g_strerror (errno));
_wapi_set_last_error_from_errno ();
- g_free (filename);
MONO_ENTER_GC_SAFE;
close (fd);
MONO_EXIT_GC_SAFE;
-
+
return(INVALID_HANDLE_VALUE);
}
- if (share_allows_open (&statbuf, sharemode, fileaccess,
- &file_handle.share_info) == FALSE) {
- mono_w32error_set_last (ERROR_SHARING_VIOLATION);
+#ifndef S_ISFIFO
+#define S_ISFIFO(m) ((m & S_IFIFO) != 0)
+#endif
+ if (S_ISFIFO (statbuf.st_mode)) {
+ type = MONO_FDTYPE_PIPE;
+ /* maintain invariant that pipes have no filename */
g_free (filename);
+ filename = NULL;
+ } else if (S_ISCHR (statbuf.st_mode)) {
+ type = MONO_FDTYPE_CONSOLE;
+ } else {
+ type = MONO_FDTYPE_FILE;
+ }
+
+ filehandle = file_data_create (type, fd);
+ filehandle->filename = filename;
+ filehandle->fileaccess = fileaccess;
+ filehandle->sharemode = sharemode;
+ filehandle->attrs = attrs;
+
+ if (!share_allows_open (&statbuf, filehandle->sharemode, filehandle->fileaccess, &filehandle->share_info)) {
+ mono_w32error_set_last (ERROR_SHARING_VIOLATION);
MONO_ENTER_GC_SAFE;
- close (fd);
+ close (((MonoFDHandle*) filehandle)->fd);
MONO_EXIT_GC_SAFE;
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return (INVALID_HANDLE_VALUE);
}
- if (file_handle.share_info == NULL) {
+ if (!filehandle->share_info) {
/* No space, so no more files can be opened */
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No space in the share table", __func__);
mono_w32error_set_last (ERROR_TOO_MANY_OPEN_FILES);
MONO_ENTER_GC_SAFE;
- close (fd);
+ close (((MonoFDHandle*) filehandle)->fd);
MONO_EXIT_GC_SAFE;
- g_free (filename);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return(INVALID_HANDLE_VALUE);
}
-
- file_handle.filename = filename;
-
- file_handle.fd = fd;
- file_handle.fileaccess=fileaccess;
- file_handle.sharemode=sharemode;
- file_handle.attrs=attrs;
#ifdef HAVE_POSIX_FADVISE
if (attrs & FILE_FLAG_SEQUENTIAL_SCAN) {
MONO_ENTER_GC_SAFE;
- posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+ posix_fadvise (((MonoFDHandle*) filehandle)->fd, 0, 0, POSIX_FADV_SEQUENTIAL);
MONO_EXIT_GC_SAFE;
}
if (attrs & FILE_FLAG_RANDOM_ACCESS) {
MONO_ENTER_GC_SAFE;
- posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM);
+ posix_fadvise (((MonoFDHandle*) filehandle)->fd, 0, 0, POSIX_FADV_RANDOM);
MONO_EXIT_GC_SAFE;
}
#endif
#ifdef F_RDAHEAD
if (attrs & FILE_FLAG_SEQUENTIAL_SCAN) {
MONO_ENTER_GC_SAFE;
- fcntl(fd, F_RDAHEAD, 1);
+ fcntl(((MonoFDHandle*) filehandle)->fd, F_RDAHEAD, 1);
MONO_EXIT_GC_SAFE;
}
#endif
-#ifndef S_ISFIFO
-#define S_ISFIFO(m) ((m & S_IFIFO) != 0)
-#endif
- if (S_ISFIFO (statbuf.st_mode)) {
- handle_type = MONO_W32HANDLE_PIPE;
- /* maintain invariant that pipes have no filename */
- file_handle.filename = NULL;
- g_free (filename);
- filename = NULL;
- } else if (S_ISCHR (statbuf.st_mode)) {
- handle_type = MONO_W32HANDLE_CONSOLE;
- } else {
- handle_type = MONO_W32HANDLE_FILE;
- }
+ mono_fdhandle_insert ((MonoFDHandle*) filehandle);
- MONO_ENTER_GC_SAFE; /* FIXME: mono_w32handle_new_fd should be updated with coop transitions */
- handle = mono_w32handle_new_fd (handle_type, fd, &file_handle);
- MONO_EXIT_GC_SAFE;
- if (handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating file handle", __func__);
- g_free (filename);
- MONO_ENTER_GC_SAFE;
- close (fd);
- MONO_EXIT_GC_SAFE;
-
- mono_w32error_set_last (ERROR_GEN_FAILURE);
- return(INVALID_HANDLE_VALUE);
- }
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p", __func__, handle);
-
- return(handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p", __func__, GINT_TO_POINTER(((MonoFDHandle*) filehandle)->fd));
+
+ return GINT_TO_POINTER(((MonoFDHandle*) filehandle)->fd);
}
gboolean
mono_w32file_close (gpointer handle)
{
- gboolean res;
- MONO_ENTER_GC_SAFE;
- /* FIXME: we transition here and not in file_close, pipe_close,
- * console_close because w32handle_close is not coop aware yet, but it
- * calls back into w32file. */
- res = mono_w32handle_close (handle);
- MONO_EXIT_GC_SAFE;
- return res;
+ if (!mono_fdhandle_close (GPOINTER_TO_INT (handle))) {
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ return TRUE;
}
gboolean mono_w32file_delete(const gunichar2 *name)
mono_w32error_set_last (ERROR_SHARING_VIOLATION);
return FALSE;
}
- if (shareinfo)
+ if (shareinfo) {
file_share_release (shareinfo);
+ shareinfo = NULL;
+ }
result = _wapi_rename (utf8_name, utf8_dest_name);
errno_copy = errno;
ret_utime = utime (utf8_dest, &dest_time);
MONO_EXIT_GC_SAFE;
if (ret_utime == -1)
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: file [%s] utime failed: %s", __func__, utf8_dest, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: file [%s] utime failed: %s", __func__, utf8_dest, g_strerror(errno));
g_free (utf8_src);
g_free (utf8_dest);
return ret;
}
-static MonoCoopMutex stdhandle_mutex;
-
static gpointer
_wapi_stdhandle_create (gint fd, const gchar *name)
{
- gpointer handle;
gint flags;
- MonoW32HandleFile file_handle = {0};
+ FileHandle *filehandle;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating standard handle type %s, fd %d", __func__, name, fd);
/* Invalid fd. Not really much point checking for EBADF
* specifically
*/
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fcntl error on fd %d: %s", __func__, fd, strerror(errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fcntl error on fd %d: %s", __func__, fd, g_strerror(errno));
mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
return INVALID_HANDLE_VALUE;
}
+ filehandle = file_data_create (MONO_FDTYPE_CONSOLE, fd);
+ filehandle->filename = g_strdup(name);
+
switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) {
case O_RDONLY:
- file_handle.fileaccess = GENERIC_READ;
+ filehandle->fileaccess = GENERIC_READ;
break;
case O_WRONLY:
- file_handle.fileaccess = GENERIC_WRITE;
+ filehandle->fileaccess = GENERIC_WRITE;
break;
case O_RDWR:
- file_handle.fileaccess = GENERIC_READ | GENERIC_WRITE;
+ filehandle->fileaccess = GENERIC_READ | GENERIC_WRITE;
break;
default:
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Can't figure out flags 0x%x", __func__, flags);
- file_handle.fileaccess = 0;
+ filehandle->fileaccess = 0;
break;
}
- file_handle.fd = fd;
- file_handle.filename = g_strdup(name);
/* some default security attributes might be needed */
- file_handle.security_attributes = 0;
+ filehandle->security_attributes = 0;
/* Apparently input handles can't be written to. (I don't
* know if output or error handles can't be read from.)
*/
if (fd == 0)
- file_handle.fileaccess &= ~GENERIC_WRITE;
+ filehandle->fileaccess &= ~GENERIC_WRITE;
- file_handle.sharemode = 0;
- file_handle.attrs = 0;
+ filehandle->sharemode = 0;
+ filehandle->attrs = 0;
- handle = mono_w32handle_new_fd (MONO_W32HANDLE_CONSOLE, fd, &file_handle);
- if (handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating file handle", __func__);
- mono_w32error_set_last (ERROR_GEN_FAILURE);
- return INVALID_HANDLE_VALUE;
+ if (!mono_fdhandle_try_insert ((MonoFDHandle*) filehandle)) {
+ /* we raced between 2 invocations of _wapi_stdhandle_create */
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return GINT_TO_POINTER(fd);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p", __func__, handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning handle %p", __func__, GINT_TO_POINTER(((MonoFDHandle*) filehandle)->fd));
- return handle;
+ return GINT_TO_POINTER(((MonoFDHandle*) filehandle)->fd);
}
enum {
static gpointer
mono_w32file_get_std_handle (gint stdhandle)
{
- MonoW32HandleFile *file_handle;
- gpointer handle;
+ FileHandle **filehandle;
gint fd;
const gchar *name;
- gboolean ok;
switch(stdhandle) {
case STD_INPUT_HANDLE:
g_assert_not_reached ();
}
- handle = GINT_TO_POINTER (fd);
-
- mono_coop_mutex_lock (&stdhandle_mutex);
+ if (!mono_fdhandle_lookup_and_ref(fd, (MonoFDHandle**) &filehandle)) {
+ gpointer handle;
- ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
- (gpointer *)&file_handle);
- if (ok == FALSE) {
- /* Need to create this console handle */
handle = _wapi_stdhandle_create (fd, name);
-
if (handle == INVALID_HANDLE_VALUE) {
mono_w32error_set_last (ERROR_NO_MORE_FILES);
- goto done;
+ return INVALID_HANDLE_VALUE;
}
}
-
- done:
- mono_coop_mutex_unlock (&stdhandle_mutex);
- return(handle);
+ return GINT_TO_POINTER (fd);
}
gboolean
mono_w32file_read (gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if(io_ops[type].readfile==NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].readfile (handle, buffer, numbytes, bytesread));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_read(filehandle, buffer, numbytes, bytesread);
+ break;
+ case MONO_FDTYPE_CONSOLE:
+ ret = console_read(filehandle, buffer, numbytes, bytesread);
+ break;
+ case MONO_FDTYPE_PIPE:
+ ret = pipe_read(filehandle, buffer, numbytes, bytesread);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gboolean
mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if(io_ops[type].writefile==NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].writefile (handle, buffer, numbytes, byteswritten));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_write(filehandle, buffer, numbytes, byteswritten);
+ break;
+ case MONO_FDTYPE_CONSOLE:
+ ret = console_write(filehandle, buffer, numbytes, byteswritten);
+ break;
+ case MONO_FDTYPE_PIPE:
+ ret = pipe_write(filehandle, buffer, numbytes, byteswritten);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gboolean
mono_w32file_flush (gpointer handle)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if(io_ops[type].flushfile==NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].flushfile (handle));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_flush(filehandle);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gboolean
mono_w32file_truncate (gpointer handle)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].setendoffile == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].setendoffile (handle));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_setendoffile(filehandle);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
guint32
mono_w32file_seek (gpointer handle, gint32 movedistance, gint32 *highmovedistance, guint32 method)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ guint32 ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].seek == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(INVALID_SET_FILE_POINTER);
+ return INVALID_SET_FILE_POINTER;
}
-
- return(io_ops[type].seek (handle, movedistance, highmovedistance,
- method));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_seek(filehandle, movedistance, highmovedistance, method);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return INVALID_SET_FILE_POINTER;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gint
mono_w32file_get_type(gpointer handle)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gint ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].getfiletype == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FILE_TYPE_UNKNOWN);
+ return FILE_TYPE_UNKNOWN;
}
-
- return(io_ops[type].getfiletype ());
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = FILE_TYPE_DISK;
+ break;
+ case MONO_FDTYPE_CONSOLE:
+ ret = FILE_TYPE_CHAR;
+ break;
+ case MONO_FDTYPE_PIPE:
+ ret = FILE_TYPE_PIPE;
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FILE_TYPE_UNKNOWN;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
static guint32
GetFileSize(gpointer handle, guint32 *highsize)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ guint32 ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].getfilesize == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(INVALID_FILE_SIZE);
+ return INVALID_FILE_SIZE;
}
-
- return(io_ops[type].getfilesize (handle, highsize));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_getfilesize(filehandle, highsize);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return INVALID_FILE_SIZE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gboolean
mono_w32file_get_times(gpointer handle, FILETIME *create_time, FILETIME *access_time, FILETIME *write_time)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].getfiletime == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].getfiletime (handle, create_time, access_time,
- write_time));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_getfiletime(filehandle, create_time, access_time, write_time);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
gboolean
mono_w32file_set_times(gpointer handle, const FILETIME *create_time, const FILETIME *access_time, const FILETIME *write_time)
{
- MonoW32HandleType type;
+ FileHandle *filehandle;
+ gboolean ret;
- type = mono_w32handle_get_type (handle);
-
- if (io_ops[type].setfiletime == NULL) {
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(io_ops[type].setfiletime (handle, create_time, access_time,
- write_time));
+
+ switch (((MonoFDHandle*) filehandle)->type) {
+ case MONO_FDTYPE_FILE:
+ ret = file_setfiletime(filehandle, create_time, access_time, write_time);
+ break;
+ default:
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
/* A tick is a 100-nanosecond interval. File time epoch is Midnight,
gboolean
mono_w32file_create_pipe (gpointer *readpipe, gpointer *writepipe, guint32 size)
{
- MonoW32HandleFile pipe_read_handle = {0};
- MonoW32HandleFile pipe_write_handle = {0};
- gpointer read_handle;
- gpointer write_handle;
+ FileHandle *read_filehandle, *write_filehandle;
gint filedes[2];
gint ret;
MONO_ENTER_GC_SAFE;
ret=pipe (filedes);
MONO_EXIT_GC_SAFE;
- if(ret==-1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error creating pipe: %s", __func__,
- strerror (errno));
-
+ if (ret==-1) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error creating pipe: (%d) %s",
+ __func__, errno, g_strerror (errno));
+
_wapi_set_last_error_from_errno ();
- return(FALSE);
+ return FALSE;
}
- if (filedes[0] >= mono_w32handle_fd_reserve ||
- filedes[1] >= mono_w32handle_fd_reserve) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
-
- mono_w32error_set_last (ERROR_TOO_MANY_OPEN_FILES);
-
- MONO_ENTER_GC_SAFE;
- close (filedes[0]);
- close (filedes[1]);
- MONO_EXIT_GC_SAFE;
-
- return(FALSE);
- }
-
/* filedes[0] is open for reading, filedes[1] for writing */
- pipe_read_handle.fd = filedes [0];
- pipe_read_handle.fileaccess = GENERIC_READ;
- read_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[0],
- &pipe_read_handle);
- if (read_handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating pipe read handle", __func__);
- MONO_ENTER_GC_SAFE;
- close (filedes[0]);
- close (filedes[1]);
- MONO_EXIT_GC_SAFE;
- mono_w32error_set_last (ERROR_GEN_FAILURE);
-
- return(FALSE);
- }
-
- pipe_write_handle.fd = filedes [1];
- pipe_write_handle.fileaccess = GENERIC_WRITE;
- write_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[1],
- &pipe_write_handle);
- if (write_handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating pipe write handle", __func__);
+ read_filehandle = file_data_create (MONO_FDTYPE_PIPE, filedes[0]);
+ read_filehandle->fileaccess = GENERIC_READ;
- MONO_ENTER_GC_SAFE;
- mono_w32handle_close (read_handle);
-
- close (filedes[0]);
- close (filedes[1]);
- MONO_EXIT_GC_SAFE;
- mono_w32error_set_last (ERROR_GEN_FAILURE);
-
- return(FALSE);
- }
-
- *readpipe = read_handle;
- *writepipe = write_handle;
+ write_filehandle = file_data_create (MONO_FDTYPE_PIPE, filedes[1]);
+ write_filehandle->fileaccess = GENERIC_WRITE;
+
+ mono_fdhandle_insert ((MonoFDHandle*) read_filehandle);
+ mono_fdhandle_insert ((MonoFDHandle*) write_filehandle);
+
+ *readpipe = GINT_TO_POINTER(((MonoFDHandle*) read_filehandle)->fd);
+ *writepipe = GINT_TO_POINTER(((MonoFDHandle*) write_filehandle)->fd);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning pipe: read handle %p, write handle %p",
- __func__, read_handle, write_handle);
+ __func__, GINT_TO_POINTER(((MonoFDHandle*) read_filehandle)->fd), GINT_TO_POINTER(((MonoFDHandle*) write_filehandle)->fd));
return(TRUE);
}
if (ret == -1) {
_wapi_set_last_error_from_errno ();
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: statvfs failed: %s", __func__, strerror (errno));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: statvfs failed: %s", __func__, g_strerror (errno));
return(FALSE);
}
static gboolean
LockFile (gpointer handle, guint32 offset_low, guint32 offset_high, guint32 length_low, guint32 length_high)
{
- MonoW32HandleFile *file_handle;
+ FileHandle *filehandle;
+ gboolean ret;
off_t offset, length;
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE, (gpointer *)&file_handle)) {
- g_warning ("%s: error looking up file handle %p", __func__, handle);
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (((MonoFDHandle*) filehandle)->type != MONO_FDTYPE_FILE) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return FALSE;
}
- if (!(file_handle->fileaccess & GENERIC_READ) && !(file_handle->fileaccess & GENERIC_WRITE) && !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if (!(filehandle->fileaccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return FALSE;
}
offset = ((gint64)offset_high << 32) | offset_low;
length = ((gint64)length_high << 32) | length_low;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locking handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
- handle, (gint64) offset, (gint64) length);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locking fd %d, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, ((MonoFDHandle*) filehandle)->fd, (gint64) offset, (gint64) length);
#else
if (offset_high > 0 || length_high > 0) {
mono_w32error_set_last (ERROR_INVALID_PARAMETER);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return FALSE;
}
+
offset = offset_low;
length = length_low;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locking handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
- handle, (gint64) offset, (gint64) length);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locking fd %d, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, ((MonoFDHandle*) filehandle)->fd, (gint64) offset, (gint64) length);
#endif
- return _wapi_lock_file_region (GPOINTER_TO_UINT(handle), offset, length);
+ ret = _wapi_lock_file_region (((MonoFDHandle*) filehandle)->fd, offset, length);
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
static gboolean
UnlockFile (gpointer handle, guint32 offset_low, guint32 offset_high, guint32 length_low, guint32 length_high)
{
- MonoW32HandleFile *file_handle;
+ FileHandle *filehandle;
+ gboolean ret;
off_t offset, length;
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE, (gpointer *)&file_handle)) {
- g_warning ("%s: error looking up file handle %p", __func__, handle);
+ if (!mono_fdhandle_lookup_and_ref(GPOINTER_TO_INT(handle), (MonoFDHandle**) &filehandle)) {
mono_w32error_set_last (ERROR_INVALID_HANDLE);
return FALSE;
}
- if (!(file_handle->fileaccess & GENERIC_READ) && !(file_handle->fileaccess & GENERIC_WRITE) && !(file_handle->fileaccess & GENERIC_ALL)) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
+ if (((MonoFDHandle*) filehandle)->type != MONO_FDTYPE_FILE) {
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return FALSE;
+ }
+
+ if (!(filehandle->fileaccess & (GENERIC_READ | GENERIC_WRITE | GENERIC_ALL))) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, ((MonoFDHandle*) filehandle)->fd, filehandle->fileaccess);
mono_w32error_set_last (ERROR_ACCESS_DENIED);
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
return FALSE;
}
offset = ((gint64)offset_high << 32) | offset_low;
length = ((gint64)length_high << 32) | length_low;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
- handle, (gint64) offset, (gint64) length);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking fd %d, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, ((MonoFDHandle*) filehandle)->fd, (gint64) offset, (gint64) length);
#else
offset = offset_low;
length = length_low;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, handle, (gint64) offset, (gint64) length);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking fd %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, ((MonoFDHandle*) filehandle)->fd, (gint64) offset, (gint64) length);
#endif
- return _wapi_unlock_file_region (GPOINTER_TO_UINT(handle), offset, length);
+ ret = _wapi_unlock_file_region (((MonoFDHandle*) filehandle)->fd, offset, length);
+
+ mono_fdhandle_unref ((MonoFDHandle*) filehandle);
+ return ret;
}
void
mono_w32file_init (void)
{
- mono_coop_mutex_init (&stdhandle_mutex);
- mono_coop_mutex_init (&file_share_mutex);
+ MonoFDHandleCallback file_data_callbacks = {
+ .close = file_data_close,
+ .destroy = file_data_destroy
+ };
+
+ mono_fdhandle_register (MONO_FDTYPE_FILE, &file_data_callbacks);
+ mono_fdhandle_register (MONO_FDTYPE_CONSOLE, &file_data_callbacks);
+ mono_fdhandle_register (MONO_FDTYPE_PIPE, &file_data_callbacks);
- mono_w32handle_register_ops (MONO_W32HANDLE_FILE, &_wapi_file_ops);
- mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
- mono_w32handle_register_ops (MONO_W32HANDLE_FIND, &_wapi_find_ops);
- mono_w32handle_register_ops (MONO_W32HANDLE_PIPE, &_wapi_pipe_ops);
+ mono_coop_mutex_init (&file_share_mutex);
-/* mono_w32handle_register_capabilities (MONO_W32HANDLE_FILE, */
-/* MONO_W32HANDLE_CAP_WAIT); */
-/* mono_w32handle_register_capabilities (MONO_W32HANDLE_CONSOLE, */
-/* MONO_W32HANDLE_CAP_WAIT); */
+ mono_w32handle_register_ops (MONO_W32HANDLE_FIND, &_wapi_find_ops);
if (g_hasenv ("MONO_STRICT_IO_EMULATION"))
lock_while_writing = TRUE;
ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, HANDLE source_handle,
HANDLE target_process_handle, HANDLE *target_handle, gint32 access, gint32 inherit, gint32 options, gint32 *error)
{
- /* This is only used on Windows */
+#ifndef HOST_WIN32
+ *target_handle = mono_w32handle_duplicate (source_handle);
+#else
gboolean ret;
-
-#ifdef HOST_WIN32
+
MONO_ENTER_GC_SAFE;
ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
MONO_EXIT_GC_SAFE;
-#else
- *target_handle = mono_w32handle_duplicate (source_handle);
- ret = TRUE;
-#endif
- if(ret==FALSE) {
+ if (!ret) {
*error = mono_w32error_get_last ();
/* FIXME: throw an exception? */
return(FALSE);
}
-
+#endif
+
return(TRUE);
}
#define SLOT_OFFSET(x) (x % HANDLE_PER_SLOT)
static MonoW32HandleBase *private_handles [SLOT_MAX];
-static guint32 private_handles_count = 0;
-static guint32 private_handles_slots_count = 0;
-
-guint32 mono_w32handle_fd_reserve;
+static guint32 private_handles_size = 0;
/*
* This is an internal handle which is used for handling waiting for multiple handles.
static gboolean shutting_down = FALSE;
-static gboolean
-type_is_fd (MonoW32HandleType type)
-{
- switch (type) {
- case MONO_W32HANDLE_FILE:
- case MONO_W32HANDLE_CONSOLE:
- case MONO_W32HANDLE_SOCKET:
- case MONO_W32HANDLE_PIPE:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
static gboolean
mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
{
g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
== MONO_W32HANDLE_COUNT);
- /* This is needed by the code in mono_w32handle_new_internal */
- mono_w32handle_fd_reserve = (eg_getdtablesize () + (HANDLE_PER_SLOT - 1)) & ~(HANDLE_PER_SLOT - 1);
-
- do {
- /*
- * The entries in private_handles reserved for fds are allocated lazily to
- * save memory.
- */
-
- private_handles_count += HANDLE_PER_SLOT;
- private_handles_slots_count ++;
- } while(mono_w32handle_fd_reserve > private_handles_count);
-
mono_os_mutex_init (&scan_mutex);
mono_os_cond_init (&global_signal_cond);
static gsize
mono_w32handle_ops_typesize (MonoW32HandleType type);
-static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
- MonoW32HandleType type, gpointer handle_specific)
-{
- g_assert (handle->ref == 0);
-
- handle->type = type;
- handle->signalled = FALSE;
- handle->ref = 1;
-
- mono_os_cond_init (&handle->signal_cond);
- mono_os_mutex_init (&handle->signal_mutex);
-
- if (handle_specific)
- handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
-}
-
/*
* mono_w32handle_new_internal:
* @type: Init handle to this type
* descriptors
*/
- if (last < mono_w32handle_fd_reserve) {
- last = mono_w32handle_fd_reserve;
+ if (last == 0) {
+ /* We need to go from 1 since a handle of value 0 can be considered invalid in managed code */
+ last = 1;
} else {
retry = TRUE;
}
again:
count = last;
- for(i = SLOT_INDEX (count); i < private_handles_slots_count; i++) {
+ for(i = SLOT_INDEX (count); i < private_handles_size; i++) {
if (private_handles [i]) {
for (k = SLOT_OFFSET (count); k < HANDLE_PER_SLOT; k++) {
MonoW32HandleBase *handle = &private_handles [i][k];
if(handle->type == MONO_W32HANDLE_UNUSED) {
last = count + 1;
- mono_w32handle_init_handle (handle, type, handle_specific);
+ g_assert (handle->ref == 0);
+
+ handle->type = type;
+ handle->signalled = FALSE;
+ handle->ref = 1;
+
+ mono_os_cond_init (&handle->signal_cond);
+ mono_os_mutex_init (&handle->signal_mutex);
+
+ if (handle_specific)
+ handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
+
return (count);
}
count++;
}
}
- if(retry && last > mono_w32handle_fd_reserve) {
+ if (retry) {
/* Try again from the beginning */
- last = mono_w32handle_fd_reserve;
+ last = 1;
+ retry = FALSE;
goto again;
}
/* Will need to expand the array. The caller will sort it out */
- return(0);
+ return G_MAXUINT32;
}
gpointer
mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
{
- guint32 handle_idx = 0;
+ guint32 handle_idx;
gpointer handle;
g_assert (!shutting_down);
- g_assert(!type_is_fd(type));
-
mono_os_mutex_lock (&scan_mutex);
- while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
+ while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == G_MAXUINT32) {
/* Try and expand the array, and have another go */
- int idx = SLOT_INDEX (private_handles_count);
- if (idx >= SLOT_MAX) {
- break;
- }
+ if (private_handles_size >= SLOT_MAX) {
+ mono_os_mutex_unlock (&scan_mutex);
- private_handles [idx] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+ /* We ran out of slots */
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
+ return INVALID_HANDLE_VALUE;
+ }
- private_handles_count += HANDLE_PER_SLOT;
- private_handles_slots_count ++;
+ private_handles [private_handles_size ++] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
}
mono_os_mutex_unlock (&scan_mutex);
- if (handle_idx == 0) {
- /* We ran out of slots */
- handle = INVALID_HANDLE_VALUE;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle", __func__, mono_w32handle_ops_typename (type));
- goto done;
- }
-
- /* Make sure we left the space for fd mappings */
- g_assert (handle_idx >= mono_w32handle_fd_reserve);
-
handle = GUINT_TO_POINTER (handle_idx);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
-done:
return(handle);
}
-gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
- gpointer handle_specific)
-{
- MonoW32HandleBase *handle_data;
- int fd_index, fd_offset;
-
- g_assert (!shutting_down);
-
- g_assert(type_is_fd(type));
-
- if (fd >= mono_w32handle_fd_reserve) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is too big", __func__, mono_w32handle_ops_typename (type));
-
- return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
- }
-
- fd_index = SLOT_INDEX (fd);
- fd_offset = SLOT_OFFSET (fd);
-
- mono_os_mutex_lock (&scan_mutex);
- /* Initialize the array entries on demand */
- if (!private_handles [fd_index]) {
- if (!private_handles [fd_index])
- private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
- }
-
- handle_data = &private_handles [fd_index][fd_offset];
-
- if (handle_data->type != MONO_W32HANDLE_UNUSED) {
- mono_os_mutex_unlock (&scan_mutex);
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: failed to create %s handle, fd is already in use", __func__, mono_w32handle_ops_typename (type));
- /* FIXME: clean up this handle? We can't do anything
- * with the fd, cos thats the new one
- */
- return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
- }
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: create %s handle %p", __func__, mono_w32handle_ops_typename (type), GUINT_TO_POINTER(fd));
-
- mono_w32handle_init_handle (handle_data, type, handle_specific);
-
- mono_os_mutex_unlock (&scan_mutex);
-
- return(GUINT_TO_POINTER(fd));
-}
-
static gboolean
mono_w32handle_ref_core (gpointer handle, MonoW32HandleBase *handle_data);
return handle;
if (!mono_w32handle_lookup_data (handle, &handle_data))
return INVALID_HANDLE_VALUE;
- if (handle == (gpointer) 0 && handle_data->type != MONO_W32HANDLE_CONSOLE)
- return handle;
if (!mono_w32handle_ref_core (handle, handle_data))
g_error ("%s: failed to ref handle %p", __func__, handle);
return FALSE;
if (!mono_w32handle_lookup_data (handle, &handle_data))
return FALSE;
- if (handle == (gpointer) 0 && handle_data->type != MONO_W32HANDLE_CONSOLE) {
- /* Problem: because we map file descriptors to the
- * same-numbered handle we can't tell the difference
- * between a bogus handle and the handle to stdin.
- * Assume that it's the console handle if that handle
- * exists... */
- return FALSE;
- }
destroy = mono_w32handle_unref_core (handle, handle_data);
if (destroy)
mono_os_mutex_lock (&scan_mutex);
- for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
+ for (i = SLOT_INDEX (0); i < private_handles_size; i++) {
if (!private_handles [i])
continue;
for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
w32handle_destroy (handle);
}
-static void
-mono_w32handle_ops_close (gpointer handle, gpointer data);
-
-void
-mono_w32handle_force_close (gpointer handle, gpointer data)
-{
- mono_w32handle_ops_close (handle, data);
-}
-
void
mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops)
{
return (NULL);
}
-static void
-mono_w32handle_ops_close (gpointer handle, gpointer data)
-{
- MonoW32HandleBase *handle_data;
- MonoW32HandleType type;
-
- if (!mono_w32handle_lookup_data (handle, &handle_data)) {
- return;
- }
-
- type = handle_data->type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->close != NULL) {
- handle_ops[type]->close (handle, data);
- }
-}
-
static void
mono_w32handle_ops_details (MonoW32HandleType type, gpointer data)
{
typedef enum {
MONO_W32HANDLE_UNUSED = 0,
- MONO_W32HANDLE_FILE,
- MONO_W32HANDLE_CONSOLE,
- MONO_W32HANDLE_THREAD,
MONO_W32HANDLE_SEM,
MONO_W32HANDLE_MUTEX,
MONO_W32HANDLE_EVENT,
- MONO_W32HANDLE_SOCKET,
MONO_W32HANDLE_FIND,
MONO_W32HANDLE_PROCESS,
- MONO_W32HANDLE_PIPE,
MONO_W32HANDLE_NAMEDMUTEX,
MONO_W32HANDLE_NAMEDSEM,
MONO_W32HANDLE_NAMEDEVENT,
MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
} MonoW32HandleCapability;
-extern guint32 mono_w32handle_fd_reserve;
-
void
mono_w32handle_init (void);
gpointer
mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
-gpointer
-mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
-
gpointer
mono_w32handle_duplicate (gpointer handle);
gboolean
mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
-void
-mono_w32handle_force_close (gpointer handle, gpointer data);
-
void
mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
dup2 (err_fd, 2);
/* Close all file descriptors */
- for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
+ for (i = eg_getdtablesize() - 1; i > 2; i--)
close (i);
#ifdef DEBUG_ENABLED
gint32
mono_w32socket_convert_error (gint error);
+gboolean
+mono_w32socket_duplicate (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle);
+
#endif // __MONO_METADATA_W32SOCKET_INTERNALS_H__
#include "w32socket.h"
#include "w32socket-internals.h"
#include "w32error.h"
-#include "w32handle.h"
+#include "fdhandle.h"
#include "utils/mono-logger-internals.h"
#include "utils/mono-poll.h"
typedef struct {
- int domain;
- int type;
- int protocol;
- int saved_error;
- int still_readable;
-} MonoW32HandleSocket;
+ MonoFDHandle fdhandle;
+ gint domain;
+ gint type;
+ gint protocol;
+ gint saved_error;
+ gint still_readable;
+} SocketHandle;
+
+static SocketHandle*
+socket_data_create (MonoFDType type, gint fd)
+{
+ SocketHandle *sockethandle;
+
+ sockethandle = g_new0 (SocketHandle, 1);
+ mono_fdhandle_init ((MonoFDHandle*) sockethandle, type, fd);
-static guint32 in_cleanup = 0;
+ return sockethandle;
+}
static void
-socket_close (gpointer handle, gpointer data)
+socket_data_close (MonoFDHandle *fdhandle)
{
- int ret;
- MonoW32HandleSocket *socket_handle = (MonoW32HandleSocket *)data;
- MonoThreadInfo *info = mono_thread_info_current ();
+ MonoThreadInfo *info;
+ SocketHandle* sockethandle;
+ gint ret;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing socket handle %p", __func__, handle);
+ sockethandle = (SocketHandle*) fdhandle;
+ g_assert (sockethandle);
- /* Shutdown the socket for reading, to interrupt any potential
- * receives that may be blocking for data. See bug 75705. */
- shutdown (GPOINTER_TO_UINT (handle), SHUT_RD);
+ info = mono_thread_info_current ();
- do {
- ret = close (GPOINTER_TO_UINT(handle));
- } while (ret == -1 && errno == EINTR &&
- !mono_thread_info_is_interrupt_state (info));
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: closing fd %d", __func__, ((MonoFDHandle*) sockethandle)->fd);
+ /* Shutdown the socket for reading, to interrupt any potential
+ * receives that may be blocking for data. See bug 75705. */
+ MONO_ENTER_GC_SAFE;
+ shutdown (((MonoFDHandle*) sockethandle)->fd, SHUT_RD);
+ MONO_EXIT_GC_SAFE;
+
+retry_close:
+ MONO_ENTER_GC_SAFE;
+ ret = close (((MonoFDHandle*) sockethandle)->fd);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
- gint errnum = errno;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: close error: %s", __func__, g_strerror (errno));
- if (!in_cleanup)
- mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ if (errno == EINTR && !mono_thread_info_is_interrupt_state (info))
+ goto retry_close;
}
- if (!in_cleanup)
- socket_handle->saved_error = 0;
+ sockethandle->saved_error = 0;
}
static void
-socket_details (gpointer data)
+socket_data_destroy (MonoFDHandle *fdhandle)
{
- /* FIXME: do something */
-}
+ SocketHandle *sockethandle;
-static const gchar*
-socket_typename (void)
-{
- return "Socket";
-}
+ sockethandle = (SocketHandle*) fdhandle;
+ g_assert (sockethandle);
-static gsize
-socket_typesize (void)
-{
- return sizeof (MonoW32HandleSocket);
+ g_free (sockethandle);
}
-static MonoW32HandleOps ops = {
- socket_close, /* close */
- NULL, /* signal */
- NULL, /* own */
- NULL, /* is_owned */
- NULL, /* special_wait */
- NULL, /* prewait */
- socket_details, /* details */
- socket_typename, /* typename */
- socket_typesize, /* typesize */
-};
-
void
mono_w32socket_initialize (void)
{
- mono_w32handle_register_ops (MONO_W32HANDLE_SOCKET, &ops);
-}
-
-static gboolean
-cleanup_close (gpointer handle, gpointer data, gpointer user_data)
-{
- if (mono_w32handle_get_type (handle) == MONO_W32HANDLE_SOCKET)
- mono_w32handle_force_close (handle, data);
+ MonoFDHandleCallback socket_data_callbacks = {
+ .close = socket_data_close,
+ .destroy = socket_data_destroy
+ };
- return FALSE;
+ mono_fdhandle_register (MONO_FDTYPE_SOCKET, &socket_data_callbacks);
}
void
mono_w32socket_cleanup (void)
{
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: cleaning up", __func__);
-
- in_cleanup = 1;
- mono_w32handle_foreach (cleanup_close, NULL);
- in_cleanup = 0;
}
SOCKET
mono_w32socket_accept (SOCKET sock, struct sockaddr *addr, socklen_t *addrlen, gboolean blocking)
{
- gpointer handle;
- gpointer new_handle;
- MonoW32HandleSocket *socket_handle;
- MonoW32HandleSocket new_socket_handle;
- SOCKET new_fd;
+ SocketHandle *sockethandle, *accepted_socket_data;
MonoThreadInfo *info;
+ gint accepted_fd;
if (addr != NULL && *addrlen < sizeof(struct sockaddr)) {
mono_w32socket_set_last_error (WSAEFAULT);
return INVALID_SOCKET;
}
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
return INVALID_SOCKET;
}
- info = mono_thread_info_current ();
-
- do {
- new_fd = accept (sock, addr, addrlen);
- } while (new_fd == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
-
- if (new_fd == -1) {
- gint errnum = errno;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: accept error: %s", __func__, g_strerror(errno));
- mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return INVALID_SOCKET;
}
- if (new_fd >= mono_w32handle_fd_reserve) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
-
- mono_w32socket_set_last_error (WSASYSCALLFAILURE);
+ info = mono_thread_info_current ();
- close (new_fd);
+ do {
+ MONO_ENTER_GC_SAFE;
+ accepted_fd = accept (((MonoFDHandle*) sockethandle)->fd, addr, addrlen);
+ MONO_EXIT_GC_SAFE;
+ } while (accepted_fd == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
+ if (accepted_fd == -1) {
+ gint error = mono_w32socket_convert_error (errno);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: accept error: %s", __func__, g_strerror(errno));
+ mono_w32socket_set_last_error (error);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return INVALID_SOCKET;
}
- new_socket_handle.domain = socket_handle->domain;
- new_socket_handle.type = socket_handle->type;
- new_socket_handle.protocol = socket_handle->protocol;
- new_socket_handle.still_readable = 1;
+ accepted_socket_data = socket_data_create (MONO_FDTYPE_SOCKET, accepted_fd);
+ accepted_socket_data->domain = sockethandle->domain;
+ accepted_socket_data->type = sockethandle->type;
+ accepted_socket_data->protocol = sockethandle->protocol;
+ accepted_socket_data->still_readable = 1;
- new_handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, new_fd,
- &new_socket_handle);
- if(new_handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating socket handle", __func__);
- mono_w32socket_set_last_error (ERROR_GEN_FAILURE);
- return INVALID_SOCKET;
- }
+ mono_fdhandle_insert ((MonoFDHandle*) accepted_socket_data);
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning newly accepted socket handle %p with",
- __func__, new_handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning accepted handle %p", __func__, GINT_TO_POINTER(((MonoFDHandle*) accepted_socket_data)->fd));
- return new_fd;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ return ((MonoFDHandle*) accepted_socket_data)->fd;
}
int
mono_w32socket_connect (SOCKET sock, const struct sockaddr *addr, int addrlen, gboolean blocking)
{
- gpointer handle;
- MonoW32HandleSocket *socket_handle;
+ SocketHandle *sockethandle;
+ gint ret;
+
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- if (connect (sock, addr, addrlen) == -1) {
+ MONO_ENTER_GC_SAFE;
+ ret = connect (((MonoFDHandle*) sockethandle)->fd, addr, addrlen);
+ MONO_EXIT_GC_SAFE;
+ if (ret == -1) {
MonoThreadInfo *info;
mono_pollfd fds;
gint errnum, so_error;
if (errnum != WSAEWOULDBLOCK) {
/* ECONNRESET means the socket was closed by another thread */
/* Async close on mac raises ECONNABORTED. */
- socket_handle->saved_error = errnum;
+ sockethandle->saved_error = errnum;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
info = mono_thread_info_current ();
- fds.fd = sock;
+ fds.fd = ((MonoFDHandle*) sockethandle)->fd;
fds.events = MONO_POLLOUT;
- while (mono_poll (&fds, 1, -1) == -1 && !mono_thread_info_is_interrupt_state (info)) {
+ for (;;) {
+ MONO_ENTER_GC_SAFE;
+ ret = mono_poll (&fds, 1, -1);
+ MONO_EXIT_GC_SAFE;
+ if (ret != -1 || mono_thread_info_is_interrupt_state (info))
+ break;
+
if (errno != EINTR) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: connect poll error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
}
len = sizeof(so_error);
- if (getsockopt (sock, SOL_SOCKET, SO_ERROR, &so_error, &len) == -1) {
+ MONO_ENTER_GC_SAFE;
+ ret = getsockopt (((MonoFDHandle*) sockethandle)->fd, SOL_SOCKET, SO_ERROR, &so_error, &len);
+ MONO_EXIT_GC_SAFE;
+ if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: connect getsockopt error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
gint errnum = mono_w32socket_convert_error (so_error);
/* Need to save this socket error */
- socket_handle->saved_error = errnum;
+ sockethandle->saved_error = errnum;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: connect getsockopt returned error: %s",
__func__, g_strerror (so_error));
mono_w32socket_set_last_error (errnum);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
int
mono_w32socket_recvfrom (SOCKET sock, char *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, gboolean blocking)
{
- gpointer handle;
- MonoW32HandleSocket *socket_handle;
+ SocketHandle *sockethandle;
int ret;
MonoThreadInfo *info;
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
info = mono_thread_info_current ();
do {
- ret = recvfrom (sock, buf, len, flags, from, fromlen);
+ MONO_ENTER_GC_SAFE;
+ ret = recvfrom (((MonoFDHandle*) sockethandle)->fd, buf, len, flags, from, fromlen);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == 0 && len > 0) {
* still_readable != 1 then shutdown
* (SHUT_RD|SHUT_RDWR) has been called locally.
*/
- if (socket_handle->still_readable != 1) {
+ if (sockethandle->still_readable != 1) {
ret = -1;
errno = EINTR;
}
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: recv error: %s", __func__, g_strerror(errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return ret;
}
int
mono_w32socket_recvbuffers (SOCKET sock, WSABUF *buffers, guint32 count, guint32 *received, guint32 *flags, gpointer overlapped, gpointer complete, gboolean blocking)
{
- MonoW32HandleSocket *socket_handle;
+ SocketHandle *sockethandle;
MonoThreadInfo *info;
- gpointer handle;
gint ret;
struct msghdr hdr;
g_assert (overlapped == NULL);
g_assert (complete == NULL);
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
wsabuf_to_msghdr (buffers, count, &hdr);
do {
- ret = recvmsg (sock, &hdr, *flags);
+ MONO_ENTER_GC_SAFE;
+ ret = recvmsg (((MonoFDHandle*) sockethandle)->fd, &hdr, *flags);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
msghdr_iov_free (&hdr);
if (ret == 0) {
/* see mono_w32socket_recvfrom */
- if (socket_handle->still_readable != 1) {
+ if (sockethandle->still_readable != 1) {
ret = -1;
errno = EINTR;
}
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: recvmsg error: %s", __func__, g_strerror(errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
*received = ret;
*flags = hdr.msg_flags;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
int
mono_w32socket_send (SOCKET sock, char *buf, int len, int flags, gboolean blocking)
{
- gpointer handle;
+ SocketHandle *sockethandle;
int ret;
MonoThreadInfo *info;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
info = mono_thread_info_current ();
do {
- ret = send (sock, buf, len, flags);
+ MONO_ENTER_GC_SAFE;
+ ret = send (((MonoFDHandle*) sockethandle)->fd, buf, len, flags);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
/* At least linux returns EAGAIN/EWOULDBLOCK when the timeout has been set on
* a blocking socket. See bug #599488 */
if (errnum == EAGAIN) {
- ret = fcntl (sock, F_GETFL, 0);
+ MONO_ENTER_GC_SAFE;
+ ret = fcntl (((MonoFDHandle*) sockethandle)->fd, F_GETFL, 0);
+ MONO_EXIT_GC_SAFE;
if (ret != -1 && (ret & O_NONBLOCK) == 0)
errnum = ETIMEDOUT;
}
#endif /* O_NONBLOCK */
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return ret;
}
int
mono_w32socket_sendto (SOCKET sock, const char *buf, int len, int flags, const struct sockaddr *to, int tolen, gboolean blocking)
{
- gpointer handle;
+ SocketHandle *sockethandle;
int ret;
MonoThreadInfo *info;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
info = mono_thread_info_current ();
do {
- ret = sendto (sock, buf, len, flags, to, tolen);
+ MONO_ENTER_GC_SAFE;
+ ret = sendto (((MonoFDHandle*) sockethandle)->fd, buf, len, flags, to, tolen);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: send error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return ret;
}
{
struct msghdr hdr;
MonoThreadInfo *info;
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
g_assert (overlapped == NULL);
g_assert (complete == NULL);
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
wsabuf_to_msghdr (buffers, count, &hdr);
do {
- ret = sendmsg (sock, &hdr, flags);
+ MONO_ENTER_GC_SAFE;
+ ret = sendmsg (((MonoFDHandle*) sockethandle)->fd, &hdr, flags);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
msghdr_iov_free (&hdr);
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sendmsg error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
*sent = ret;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
mono_w32socket_transmit_file (SOCKET sock, gpointer file_handle, TRANSMIT_FILE_BUFFERS *buffers, guint32 flags, gboolean blocking)
{
MonoThreadInfo *info;
- gpointer handle;
+ SocketHandle *sockethandle;
gint file;
gssize ret;
#if defined(HAVE_SENDFILE) && (defined(__linux__) || defined(DARWIN))
gchar *buffer;
#endif
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
- return FALSE;
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
}
/* Write the header */
if (buffers != NULL && buffers->Head != NULL && buffers->HeadLength > 0) {
- ret = mono_w32socket_send (sock, buffers->Head, buffers->HeadLength, 0, FALSE);
- if (ret == SOCKET_ERROR)
+ ret = mono_w32socket_send (((MonoFDHandle*) sockethandle)->fd, buffers->Head, buffers->HeadLength, 0, FALSE);
+ if (ret == SOCKET_ERROR) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return FALSE;
+ }
}
info = mono_thread_info_current ();
file = GPOINTER_TO_INT (file_handle);
#if defined(HAVE_SENDFILE) && (defined(__linux__) || defined(DARWIN))
+ MONO_ENTER_GC_SAFE;
ret = fstat (file, &statbuf);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
do {
+ MONO_ENTER_GC_SAFE;
#ifdef __linux__
- ret = sendfile (sock, file, NULL, statbuf.st_size);
+ ret = sendfile (((MonoFDHandle*) sockethandle)->fd, file, NULL, statbuf.st_size);
#elif defined(DARWIN)
/* TODO: header/tail could be sent in the 5th argument */
/* TODO: Might not send the entire file for non-blocking sockets */
- ret = sendfile (file, sock, 0, &statbuf.st_size, NULL, 0);
+ ret = sendfile (file, ((MonoFDHandle*) sockethandle)->fd, 0, &statbuf.st_size, NULL, 0);
#endif
+ MONO_EXIT_GC_SAFE;
} while (ret != -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
#else
buffer = g_malloc (SF_BUFFER_SIZE);
do {
do {
+ MONO_ENTER_GC_SAFE;
ret = read (file, buffer, SF_BUFFER_SIZE);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1 || ret == 0)
break;
do {
- ret = send (sock, buffer, ret, 0); /* short sends? enclose this in a loop? */
+ MONO_ENTER_GC_SAFE;
+ ret = send (((MonoFDHandle*) sockethandle)->fd, buffer, ret, 0); /* short sends? enclose this in a loop? */
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
} while (ret != -1 && errno == EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
gint errnum = errno;
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return FALSE;
}
/* Write the tail */
if (buffers != NULL && buffers->Tail != NULL && buffers->TailLength > 0) {
- ret = mono_w32socket_send (sock, buffers->Tail, buffers->TailLength, 0, FALSE);
- if (ret == SOCKET_ERROR)
+ ret = mono_w32socket_send (((MonoFDHandle*) sockethandle)->fd, buffers->Tail, buffers->TailLength, 0, FALSE);
+ if (ret == SOCKET_ERROR) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return FALSE;
+ }
}
if ((flags & TF_DISCONNECT) == TF_DISCONNECT)
- mono_w32handle_close (handle);
+ mono_w32socket_close (((MonoFDHandle*) sockethandle)->fd);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return TRUE;
}
SOCKET
mono_w32socket_socket (int domain, int type, int protocol)
{
- MonoW32HandleSocket socket_handle = {0};
- gpointer handle;
- SOCKET sock;
-
- socket_handle.domain = domain;
- socket_handle.type = type;
- socket_handle.protocol = protocol;
- socket_handle.still_readable = 1;
-
- sock = socket (domain, type, protocol);
- if (sock == -1 && domain == AF_INET && type == SOCK_RAW &&
- protocol == 0) {
- /* Retry with protocol == 4 (see bug #54565) */
- // https://bugzilla.novell.com/show_bug.cgi?id=MONO54565
- socket_handle.protocol = 4;
- sock = socket (AF_INET, SOCK_RAW, 4);
- }
+ SocketHandle *sockethandle;
+ gint fd;
+
+retry_socket:
+ MONO_ENTER_GC_SAFE;
+ fd = socket (domain, type, protocol);
+ MONO_EXIT_GC_SAFE;
+ if (fd == -1) {
+ if (domain == AF_INET && type == SOCK_RAW && protocol == 0) {
+ /* Retry with protocol == 4 (see bug #54565) */
+ // https://bugzilla.novell.com/show_bug.cgi?id=MONO54565
+ protocol = 4;
+ goto retry_socket;
+ }
- if (sock == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: socket error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
return INVALID_SOCKET;
}
- if (sock >= mono_w32handle_fd_reserve) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big (%d >= %d)",
- __func__, sock, mono_w32handle_fd_reserve);
-
- mono_w32socket_set_last_error (WSASYSCALLFAILURE);
- close (sock);
-
- return INVALID_SOCKET;
- }
+ sockethandle = socket_data_create(MONO_FDTYPE_SOCKET, fd);
+ sockethandle->domain = domain;
+ sockethandle->type = type;
+ sockethandle->protocol = protocol;
+ sockethandle->still_readable = 1;
/* .net seems to set this by default for SOCK_STREAM, not for
* SOCK_DGRAM (see bug #36322)
{
int ret, true_ = 1;
- ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &true_, sizeof (true_));
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (((MonoFDHandle*) sockethandle)->fd, SOL_SOCKET, SO_REUSEADDR, &true_, sizeof (true_));
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
- close (sock);
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error setting SO_REUSEADDR", __func__);
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+
+ MONO_ENTER_GC_SAFE;
+ close (((MonoFDHandle*) sockethandle)->fd);
+ MONO_EXIT_GC_SAFE;
+
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return INVALID_SOCKET;
}
}
+ mono_fdhandle_insert ((MonoFDHandle*) sockethandle);
- handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, sock, &socket_handle);
- if (handle == INVALID_HANDLE_VALUE) {
- g_warning ("%s: error creating socket handle", __func__);
- mono_w32socket_set_last_error (WSASYSCALLFAILURE);
- close (sock);
- return INVALID_SOCKET;
- }
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning socket handle %p", __func__, handle);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning socket handle %p", __func__, GINT_TO_POINTER(((MonoFDHandle*) sockethandle)->fd));
- return sock;
+ return ((MonoFDHandle*) sockethandle)->fd;
}
gint
mono_w32socket_bind (SOCKET sock, struct sockaddr *addr, socklen_t addrlen)
{
- gpointer handle;
+ SocketHandle *sockethandle;
int ret;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- ret = bind (sock, addr, addrlen);
+ MONO_ENTER_GC_SAFE;
+ ret = bind (((MonoFDHandle*) sockethandle)->fd, addr, addrlen);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: bind error: %s", __func__, g_strerror(errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gint
mono_w32socket_getpeername (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- ret = getpeername (sock, name, namelen);
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ MONO_ENTER_GC_SAFE;
+ ret = getpeername (((MonoFDHandle*) sockethandle)->fd, name, namelen);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: getpeername error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gint
mono_w32socket_getsockname (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- ret = getsockname (sock, name, namelen);
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ MONO_ENTER_GC_SAFE;
+ ret = getsockname (((MonoFDHandle*) sockethandle)->fd, name, namelen);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: getsockname error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gint
mono_w32socket_getsockopt (SOCKET sock, gint level, gint optname, gpointer optval, socklen_t *optlen)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
struct timeval tv;
gpointer tmp_val;
- MonoW32HandleSocket *socket_handle;
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
*optlen = sizeof (tv);
}
- ret = getsockopt (sock, level, optname, tmp_val, optlen);
+ MONO_ENTER_GC_SAFE;
+ ret = getsockopt (((MonoFDHandle*) sockethandle)->fd, level, optname, tmp_val, optlen);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: getsockopt error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (optname == SO_ERROR) {
if (*((int *)optval) != 0) {
*((int *) optval) = mono_w32socket_convert_error (*((int *)optval));
- socket_handle->saved_error = *((int *)optval);
+ sockethandle->saved_error = *((int *)optval);
} else {
- *((int *)optval) = socket_handle->saved_error;
+ *((int *)optval) = sockethandle->saved_error;
}
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gint
mono_w32socket_setsockopt (SOCKET sock, gint level, gint optname, const gpointer optval, socklen_t optlen)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
gpointer tmp_val;
#if defined (__linux__)
#endif
struct timeval tv;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
}
#endif
- ret = setsockopt (sock, level, optname, tmp_val, optlen);
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (((MonoFDHandle*) sockethandle)->fd, level, optname, tmp_val, optlen);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setsockopt error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
int type;
socklen_t type_len = sizeof (type);
- if (!getsockopt (sock, level, SO_TYPE, &type, &type_len)) {
- if (type == SOCK_DGRAM || type == SOCK_STREAM)
- setsockopt (sock, level, SO_REUSEPORT, tmp_val, optlen);
+ MONO_ENTER_GC_SAFE;
+ ret = getsockopt (((MonoFDHandle*) sockethandle)->fd, level, SO_TYPE, &type, &type_len);
+ MONO_EXIT_GC_SAFE;
+ if (!ret) {
+ if (type == SOCK_DGRAM || type == SOCK_STREAM) {
+ MONO_ENTER_GC_SAFE;
+ setsockopt (((MonoFDHandle*) sockethandle)->fd, level, SO_REUSEPORT, tmp_val, optlen);
+ MONO_EXIT_GC_SAFE;
+ }
}
}
#endif
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return ret;
}
gint
mono_w32socket_listen (SOCKET sock, gint backlog)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- ret = listen (sock, backlog);
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ MONO_ENTER_GC_SAFE;
+ ret = listen (((MonoFDHandle*) sockethandle)->fd, backlog);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: listen error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gint
mono_w32socket_shutdown (SOCKET sock, gint how)
{
- MonoW32HandleSocket *socket_handle;
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
if (how == SHUT_RD || how == SHUT_RDWR)
- socket_handle->still_readable = 0;
+ sockethandle->still_readable = 0;
- ret = shutdown (sock, how);
+ MONO_ENTER_GC_SAFE;
+ ret = shutdown (((MonoFDHandle*) sockethandle)->fd, how);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: shutdown error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return ret;
}
gint
mono_w32socket_disconnect (SOCKET sock, gboolean reuse)
{
- MonoW32HandleSocket *socket_handle;
- gpointer handle;
+ SocketHandle *sockethandle;
SOCKET newsock;
gint ret;
* SOCK_STREAM, SOCK_SEQPACKET or SOCK_RDM (according to msdn)
* if we really wanted to */
- handle = GUINT_TO_POINTER (sock);
- if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET, (gpointer *)&socket_handle)) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
- newsock = socket (socket_handle->domain, socket_handle->type, socket_handle->protocol);
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ MONO_ENTER_GC_SAFE;
+ newsock = socket (sockethandle->domain, sockethandle->type, sockethandle->protocol);
+ MONO_EXIT_GC_SAFE;
if (newsock == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: socket error: %s", __func__, g_strerror (errnum));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
* should not be a race condition between the old fd being
* closed and the new socket fd being copied over */
do {
- ret = dup2 (newsock, sock);
+ MONO_ENTER_GC_SAFE;
+ ret = dup2 (newsock, ((MonoFDHandle*) sockethandle)->fd);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EAGAIN);
if (ret == -1) {
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: dup2 error: %s", __func__, g_strerror (errnum));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ MONO_ENTER_GC_SAFE;
close (newsock);
+ MONO_EXIT_GC_SAFE;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
static gboolean
extension_disconect (SOCKET sock, OVERLAPPED *overlapped, guint32 flags, guint32 reserved)
{
- return mono_w32socket_disconnect (sock, flags & TF_REUSE_SOCKET) == 0;
+ gboolean ret;
+ MONO_ENTER_GC_UNSAFE;
+ ret = mono_w32socket_disconnect (sock, flags & TF_REUSE_SOCKET) == 0;
+ MONO_EXIT_GC_UNSAFE;
+ return ret;
}
static gboolean
extension_transmit_file (SOCKET sock, gpointer file_handle, guint32 bytes_to_write, guint32 bytes_per_send,
OVERLAPPED *ol, TRANSMIT_FILE_BUFFERS *buffers, guint32 flags)
{
- return mono_w32socket_transmit_file (sock, file_handle, buffers, flags, FALSE);
+ gboolean ret;
+ MONO_ENTER_GC_UNSAFE;
+ ret = mono_w32socket_transmit_file (sock, file_handle, buffers, flags, FALSE);
+ MONO_EXIT_GC_UNSAFE;
+ return ret;
}
static struct {
gint
mono_w32socket_ioctl (SOCKET sock, gint32 command, gchar *input, gint inputlen, gchar *output, gint outputlen, glong *written)
{
- gpointer handle;
+ SocketHandle *sockethandle;
gint ret;
gchar *buffer;
- handle = GUINT_TO_POINTER (sock);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
* actually set an error here...
*/
mono_w32socket_set_last_error (WSAEINVAL);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (outputlen < sizeof(gpointer)) {
/* Or here... */
mono_w32socket_set_last_error (WSAEINVAL);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (output == NULL) {
/* Or here */
mono_w32socket_set_last_error (WSAEINVAL);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (memcmp (guid, &extension_functions[i].guid, sizeof(GUID)) == 0) {
memcpy (output, &extension_functions[i].func, sizeof(gpointer));
*written = sizeof(gpointer);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
}
mono_w32socket_set_last_error (WSAEINVAL);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (inputlen < 3 * sizeof (guint32)) {
mono_w32socket_set_last_error (WSAEINVAL);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
onoff = *((guint32*) input);
- ret = setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof (guint32));
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (((MonoFDHandle*) sockethandle)->fd, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof (guint32));
+ MONO_EXIT_GC_SAFE;
if (ret < 0) {
mono_w32socket_set_last_error (mono_w32socket_convert_error (errno));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
keepalivetime /= 1000;
if (keepalivetime == 0 || rem >= 500)
keepalivetime++;
- ret = setsockopt (sock, IPPROTO_TCP, TCP_KEEPIDLE, &keepalivetime, sizeof (guint32));
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (((MonoFDHandle*) sockethandle)->fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalivetime, sizeof (guint32));
+ MONO_EXIT_GC_SAFE;
if (ret == 0) {
rem = keepaliveinterval % 1000;
keepaliveinterval /= 1000;
if (keepaliveinterval == 0 || rem >= 500)
keepaliveinterval++;
- ret = setsockopt (sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepaliveinterval, sizeof (guint32));
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (((MonoFDHandle*) sockethandle)->fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepaliveinterval, sizeof (guint32));
+ MONO_EXIT_GC_SAFE;
}
if (ret != 0) {
mono_w32socket_set_last_error (mono_w32socket_convert_error (errno));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
#endif
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
buffer = inputlen > 0 ? (gchar*) g_memdup (input, inputlen) : NULL;
- ret = ioctl (sock, command, buffer);
+ MONO_ENTER_GC_SAFE;
+ ret = ioctl (((MonoFDHandle*) sockethandle)->fd, command, buffer);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
g_free (buffer);
gint errnum = errno;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: WSAIoctl error: %s", __func__, g_strerror (errno));
mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
if (!buffer) {
*written = 0;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
g_free (buffer);
*written = inputlen;
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
gboolean
mono_w32socket_close (SOCKET sock)
{
- return mono_w32handle_close (GINT_TO_POINTER (sock));
+ if (!mono_fdhandle_close (sock)) {
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ return TRUE;
}
gint
-mono_w32socket_set_blocking (SOCKET socket, gboolean blocking)
+mono_w32socket_set_blocking (SOCKET sock, gboolean blocking)
{
#ifdef O_NONBLOCK
+ SocketHandle *sockethandle;
gint ret;
- gpointer handle;
- handle = GINT_TO_POINTER (socket);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
/* This works better than ioctl(...FIONBIO...)
* on Linux (it causes connect to return
* EINPROGRESS, but the ioctl doesn't seem to) */
- ret = fcntl (socket, F_GETFL, 0);
- if (ret != -1)
- ret = fcntl (socket, F_SETFL, blocking ? (ret & (~O_NONBLOCK)) : (ret | (O_NONBLOCK)));
+ MONO_ENTER_GC_SAFE;
+ ret = fcntl (((MonoFDHandle*) sockethandle)->fd, F_GETFL, 0);
+ MONO_EXIT_GC_SAFE;
+ if (ret == -1) {
+ gint errnum = mono_w32socket_convert_error (errno);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fcntl(F_GETFL) error: %s", __func__, g_strerror (errno));
+ mono_w32socket_set_last_error (errnum);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ return SOCKET_ERROR;
+ }
+ MONO_ENTER_GC_SAFE;
+ ret = fcntl (((MonoFDHandle*) sockethandle)->fd, F_SETFL, blocking ? (ret & (~O_NONBLOCK)) : (ret | (O_NONBLOCK)));
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
- gint errnum = errno;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: ioctl error: %s", __func__, g_strerror (errno));
- mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ gint errnum = mono_w32socket_convert_error (errno);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fcntl(F_SETFL) error: %s", __func__, g_strerror (errno));
+ mono_w32socket_set_last_error (errnum);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
#else
mono_w32socket_set_last_error (ERROR_NOT_SUPPORTED);
}
gint
-mono_w32socket_get_available (SOCKET socket, guint64 *amount)
+mono_w32socket_get_available (SOCKET sock, guint64 *amount)
{
+ SocketHandle *sockethandle;
gint ret;
- gpointer handle;
- handle = GINT_TO_POINTER (socket);
- if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
- mono_w32socket_set_last_error (WSAENOTSOCK);
+ if (!mono_fdhandle_lookup_and_ref(sock, (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (WSAENOTSOCK);
return SOCKET_ERROR;
}
// the ip buffer.
socklen_t optlen = sizeof (int);
- ret = getsockopt (socket, SOL_SOCKET, SO_NREAD, (gulong*) amount, &optlen);
+ MONO_ENTER_GC_SAFE;
+ ret = getsockopt (((MonoFDHandle*) sockethandle)->fd, SOL_SOCKET, SO_NREAD, (gulong*) amount, &optlen);
+ MONO_EXIT_GC_SAFE;
+ if (ret == -1) {
+ gint errnum = mono_w32socket_convert_error (errno);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: getsockopt error: %s", __func__, g_strerror (errno));
+ mono_w32socket_set_last_error (errnum);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ return SOCKET_ERROR;
+ }
#else
- ret = ioctl (socket, FIONREAD, (gulong*) amount);
-#endif
-
+ MONO_ENTER_GC_SAFE;
+ ret = ioctl (((MonoFDHandle*) sockethandle)->fd, FIONREAD, (gulong*) amount);
+ MONO_EXIT_GC_SAFE;
if (ret == -1) {
- gint errnum = errno;
+ gint errnum = mono_w32socket_convert_error (errno);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: ioctl error: %s", __func__, g_strerror (errno));
- mono_w32socket_set_last_error (mono_w32socket_convert_error (errnum));
+ mono_w32socket_set_last_error (errnum);
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return SOCKET_ERROR;
}
+#endif
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
return 0;
}
return FALSE;
#endif
}
+
+gboolean
+mono_w32socket_duplicate (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle)
+{
+ SocketHandle *sockethandle;
+
+ if (!mono_fdhandle_lookup_and_ref (GPOINTER_TO_INT(handle), (MonoFDHandle**) &sockethandle)) {
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (((MonoFDHandle*) sockethandle)->type != MONO_FDTYPE_SOCKET) {
+ mono_fdhandle_unref ((MonoFDHandle*) sockethandle);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ *duplicate_handle = handle;
+ return TRUE;
+}
{
MonoInternalThread *curthread = mono_thread_internal_current ();
SOCKET newsock = INVALID_SOCKET;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_ACCEPT_BIT, blocking, TRUE, newsock, accept, s, addr, addrlen);
+ MONO_EXIT_GC_SAFE;
return newsock;
}
int mono_w32socket_connect (SOCKET s, const struct sockaddr *name, int namelen, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_CONNECT_BIT, blocking, FALSE, ret, connect, s, name, namelen);
ret = WSAGetLastError () != 0 ? SOCKET_ERROR : 0;
+ MONO_EXIT_GC_SAFE;
return ret;
}
{
MonoInternalThread *curthread = mono_thread_internal_current ();
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, recv, s, buf, len, flags);
+ MONO_EXIT_GC_SAFE;
return ret;
}
int mono_w32socket_recvfrom (SOCKET s, char *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, recvfrom, s, buf, len, flags, from, fromlen);
+ MONO_EXIT_GC_SAFE;
return ret;
}
int mono_w32socket_recvbuffers (SOCKET s, WSABUF *lpBuffers, guint32 dwBufferCount, guint32 *lpNumberOfBytesRecvd, guint32 *lpFlags, gpointer lpOverlapped, gpointer lpCompletionRoutine, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_READ_BIT, blocking, TRUE, ret, WSARecv, s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
+ MONO_EXIT_GC_SAFE;
return ret;
}
int mono_w32socket_send (SOCKET s, char *buf, int len, int flags, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, send, s, buf, len, flags);
+ MONO_EXIT_GC_SAFE;
return ret;
}
int mono_w32socket_sendto (SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, sendto, s, buf, len, flags, to, tolen);
+ MONO_EXIT_GC_SAFE;
return ret;
}
int mono_w32socket_sendbuffers (SOCKET s, WSABUF *lpBuffers, guint32 dwBufferCount, guint32 *lpNumberOfBytesRecvd, guint32 lpFlags, gpointer lpOverlapped, gpointer lpCompletionRoutine, gboolean blocking)
{
int ret = SOCKET_ERROR;
+ MONO_ENTER_GC_SAFE;
ALERTABLE_SOCKET_CALL (FD_WRITE_BIT, blocking, FALSE, ret, WSASend, s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped, lpCompletionRoutine);
+ MONO_EXIT_GC_SAFE;
return ret;
}
{
LOGDEBUG (g_message ("%06d - Performing %s TransmitFile () on socket %d", GetCurrentThreadId (), blocking ? "blocking" : "non-blocking", hSocket));
- int error = 0;
+ int error = 0, ret;
+
+ MONO_ENTER_GC_SAFE;
+
if (blocking) {
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = WSACreateEvent ();
- if (overlapped.hEvent == WSA_INVALID_EVENT)
- return FALSE;
+ if (overlapped.hEvent == WSA_INVALID_EVENT) {
+ ret = FALSE;
+ goto done;
+ }
if (!TransmitFile (hSocket, hFile, 0, 0, &overlapped, lpTransmitBuffers, dwReserved)) {
error = WSAGetLastError ();
if (error == WSA_IO_PENDING) {
blocking ? "blocking" : "non-blocking", hSocket, error == 0, error));
WSASetLastError (error);
- return error == 0;
+ ret = error == 0;
+
+done:
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
#endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
DWORD output_bytes;
gint ret;
+ MONO_ENTER_GC_SAFE;
+
/* Use the SIO_GET_EXTENSION_FUNCTION_POINTER to determine
* the address of the disconnect method without taking
* a hard dependency on a single provider
GUID disconnect_guid = WSAID_DISCONNECTEX;
ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &disconnect_guid, sizeof (GUID), &disconnect, sizeof (LPFN_DISCONNECTEX), &output_bytes, NULL, NULL);
if (ret == 0) {
- if (!disconnect (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0))
- return WSAGetLastError ();
+ if (!disconnect (sock, NULL, reuse ? TF_REUSE_SOCKET : 0, 0)) {
+ ret = WSAGetLastError ();
+ goto done;
+ }
- return 0;
+ ret = 0;
+ goto done;
}
GUID transmit_file_guid = WSAID_TRANSMITFILE;
ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &transmit_file_guid, sizeof (GUID), &transmit_file, sizeof (LPFN_TRANSMITFILE), &output_bytes, NULL, NULL);
if (ret == 0) {
- if (!transmit_file (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0)))
- return WSAGetLastError ();
+ if (!transmit_file (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | (reuse ? TF_REUSE_SOCKET : 0))) {
+ ret = WSAGetLastError ();
+ goto done;
+ }
- return 0;
+ ret = 0;
+ goto done;
}
- return ERROR_NOT_SUPPORTED;
+ ret = ERROR_NOT_SUPPORTED;
+
+done:
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
#endif /* #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
gint
mono_w32socket_set_blocking (SOCKET sock, gboolean blocking)
{
+ gint ret;
gulong nonblocking_long = !blocking;
- return ioctlsocket (sock, FIONBIO, &nonblocking_long);
+ MONO_ENTER_GC_SAFE;
+ ret = ioctlsocket (sock, FIONBIO, &nonblocking_long);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
gint
mono_w32socket_get_available (SOCKET sock, guint64 *amount)
{
- return ioctlsocket (sock, FIONREAD, (int*) amount);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = ioctlsocket (sock, FIONREAD, (int*) amount);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
void
error_init (error);
return TRUE;
}
+
+gboolean
+mono_w32socket_duplicate (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle)
+{
+ gboolean ret;
+
+ MONO_ENTER_GC_SAFE;
+ ret = DuplicateHandle (GetCurrentProcess(), handle, GINT_TO_POINTER(targetProcessId), duplicate_handle, 0, 0, 0x00000002 /* DUPLICATE_SAME_ACCESS */);
+ MONO_EXIT_GC_SAFE;
+
+ return ret;
+}
static SOCKET
mono_w32socket_socket (int domain, int type, int protocol)
{
- return WSASocket (domain, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
+ SOCKET ret;
+ MONO_ENTER_GC_SAFE;
+ ret = WSASocket (domain, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_bind (SOCKET sock, struct sockaddr *addr, socklen_t addrlen)
{
- return bind (sock, addr, addrlen);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = bind (sock, addr, addrlen);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_getpeername (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
{
- return getpeername (sock, name, namelen);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = getpeername (sock, name, namelen);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_getsockname (SOCKET sock, struct sockaddr *name, socklen_t *namelen)
{
- return getsockname (sock, name, namelen);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = getsockname (sock, name, namelen);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_getsockopt (SOCKET sock, gint level, gint optname, gpointer optval, socklen_t *optlen)
{
- return getsockopt (sock, level, optname, optval, optlen);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = getsockopt (sock, level, optname, optval, optlen);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_setsockopt (SOCKET sock, gint level, gint optname, const gpointer optval, socklen_t optlen)
{
- return setsockopt (sock, level, optname, optval, optlen);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = setsockopt (sock, level, optname, optval, optlen);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_listen (SOCKET sock, gint backlog)
{
- return listen (sock, backlog);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = listen (sock, backlog);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_shutdown (SOCKET sock, gint how)
{
- return shutdown (sock, how);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = shutdown (sock, how);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gint
mono_w32socket_ioctl (SOCKET sock, gint32 command, gchar *input, gint inputlen, gchar *output, gint outputlen, glong *written)
{
- return WSAIoctl (sock, command, input, inputlen, output, outputlen, written, NULL, NULL);
+ gint ret;
+ MONO_ENTER_GC_SAFE;
+ ret = WSAIoctl (sock, command, input, inputlen, output, outputlen, written, NULL, NULL);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
static gboolean
mono_w32socket_close (SOCKET sock)
{
- return CloseHandle (sock);
+ gboolean ret;
+ MONO_ENTER_GC_SAFE;
+ ret = CloseHandle (sock);
+ MONO_EXIT_GC_SAFE;
+ return ret;
}
#endif /* HOST_WIN32 */
* polling system does not notify when the socket is closed */
mono_threadpool_io_remove_socket (GPOINTER_TO_INT (sock));
- MONO_ENTER_GC_SAFE;
mono_w32socket_close ((SOCKET) sock);
- MONO_EXIT_GC_SAFE;
}
gint32
return NULL;
}
- MONO_ENTER_GC_SAFE;
newsock = mono_w32socket_accept (sock, NULL, 0, blocking);
- MONO_EXIT_GC_SAFE;
-
if (newsock == INVALID_SOCKET)
*werror = mono_w32socket_get_last_error ();
error_init (error);
*werror = 0;
- MONO_ENTER_GC_SAFE;
-
ret = mono_w32socket_listen (sock, backlog);
-
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR)
*werror = mono_w32socket_get_last_error ();
}
}
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
- MONO_ENTER_GC_SAFE;
-
ret = mono_w32socket_getsockname (sock, (struct sockaddr *)sa, &salen);
-
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR) {
*werror = mono_w32socket_get_last_error ();
if (salen > 128)
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
/* Note: linux returns just 2 for AF_UNIX. Always. */
- MONO_ENTER_GC_SAFE;
-
ret = mono_w32socket_getpeername (sock, (struct sockaddr *)sa, &salen);
-
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR) {
*werror = mono_w32socket_get_last_error ();
if (salen > 128)
return;
}
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_connect (sock, sa, sa_size, blocking);
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR)
*werror = mono_w32socket_get_last_error ();
return;
}
- MONO_ENTER_GC_SAFE;
*werror = mono_w32socket_disconnect (sock, reuse);
- MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted)
}
#endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT) */
+MonoBoolean
+ves_icall_System_Net_Sockets_Socket_Duplicate_internal (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle, gint32 *werror, MonoError *error)
+{
+ error_init (error);
+
+ *werror = 0;
+ if (!mono_w32socket_duplicate (handle, targetProcessId, duplicate_handle)) {
+ *werror = mono_w32error_get_last ();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
gint32
ves_icall_System_Net_Sockets_Socket_Receive_internal (gsize sock, MonoArrayHandle buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror, gboolean blocking, MonoError *error)
{
uint32_t gchandle;
gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_recv (sock, buf, count, recvflags, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
uint32_t gchandle;
WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_recvbuffers (sock, wsabufs, count, &recv, &recvflags, NULL, NULL, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
uint32_t gchandle;
buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_recvfrom (sock, buf, count, recvflags, sa, &sa_size, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
uint32_t gchandle;
gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_send (sock, buf, count, sendflags, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
uint32_t gchandle;
WSABUF *wsabufs = MONO_ARRAY_HANDLE_PIN (buffers, WSABUF, 0, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_sendbuffers (sock, wsabufs, count, &sent, sendflags, NULL, NULL, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
uint32_t gchandle;
gchar *buf = MONO_ARRAY_HANDLE_PIN (buffer, gchar, offset, &gchandle);
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_sendto (sock, buf, count, sendflags, sa, sa_size, blocking);
- MONO_EXIT_GC_SAFE;
mono_gchandle_free (gchandle);
return;
}
- MONO_ENTER_GC_SAFE;
-
/* No need to deal with MulticastOption names here, because
* you cant getsockopt AddMembership or DropMembership (the
* int getsockopt will error, causing an exception)
ret = mono_w32socket_getsockopt (sock, system_level, system_name, &val, &valsize);
}
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR) {
*werror = mono_w32socket_get_last_error ();
return;
uint32_t gchandle;
guchar *buf = MONO_ARRAY_HANDLE_PIN (byte_val, guchar, 0, &gchandle);
- MONO_ENTER_GC_SAFE;
-
ret = mono_w32socket_getsockopt (sock, system_level, system_name, buf, &valsize);
- MONO_EXIT_GC_SAFE;
-
mono_gchandle_free (gchandle);
if (ret == SOCKET_ERROR)
return;
}
- MONO_ENTER_GC_SAFE;
-
/* Currently, the values for how (recv=0, send=1, both=2) match the BSD API */
ret = mono_w32socket_shutdown (sock, how);
-
- MONO_EXIT_GC_SAFE;
-
if (ret == SOCKET_ERROR)
*werror = mono_w32socket_get_last_error ();
o_buffer = MONO_ARRAY_HANDLE_PIN (output, gchar, 0, &o_gchandle);
}
- MONO_ENTER_GC_SAFE;
-
ret = mono_w32socket_ioctl (sock, code, i_buffer, i_len, o_buffer, o_len, &output_bytes);
- MONO_EXIT_GC_SAFE;
-
if (i_gchandle)
mono_gchandle_free (i_gchandle);
if (o_gchandle)
g_free (address);
- MONO_ENTER_GC_SAFE;
-
switch (family) {
case AF_INET: {
#if HAVE_SOCKADDR_IN_SIN_LEN
saddr.sin_len = sizeof (saddr);
#endif
+ MONO_ENTER_GC_SAFE;
ret = getnameinfo ((struct sockaddr*)&saddr, sizeof (saddr), hostname, sizeof (hostname), NULL, 0, 0) == 0;
+ MONO_EXIT_GC_SAFE;
break;
}
#ifdef HAVE_STRUCT_SOCKADDR_IN6
#if HAVE_SOCKADDR_IN6_SIN_LEN
saddr6.sin6_len = sizeof (saddr6);
#endif
+ MONO_ENTER_GC_SAFE;
ret = getnameinfo ((struct sockaddr*)&saddr6, sizeof (saddr6), hostname, sizeof (hostname), NULL, 0, 0) == 0;
+ MONO_EXIT_GC_SAFE;
break;
}
#endif
g_assert_not_reached ();
}
- MONO_EXIT_GC_SAFE;
-
if (!ret)
return FALSE;
buffers.TailLength = mono_array_handle_length (post_buffer);
}
- MONO_ENTER_GC_SAFE;
ret = mono_w32socket_transmit_file (sock, file, &buffers, flags, blocking);
- MONO_EXIT_GC_SAFE;
if (pre_buffer_gchandle)
mono_gchandle_free (pre_buffer_gchandle);
void
ves_icall_System_Net_Sockets_Socket_Disconnect_internal (gsize sock, MonoBoolean reuse, gint32 *werror, MonoError *error);
+MonoBoolean
+ves_icall_System_Net_Sockets_Socket_Duplicate_internal (gpointer handle, gint32 targetProcessId, gpointer *duplicate_handle, gint32 *werror, MonoError *error);
+
gboolean
ves_icall_System_Net_Sockets_Socket_SendFile_internal (gsize sock, MonoStringHandle filename,
MonoArrayHandle pre_buffer, MonoArrayHandle post_buffer,