+/**
+ * \file
+ */
#include <config.h>
#include <glib.h>
#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);
}
get_errno_from_g_file_error (gint error)
{
switch (error) {
-#ifdef EACCESS
+#ifdef EACCES
case G_FILE_ERROR_ACCES: return EACCES;
#endif
#ifdef ENAMETOOLONG
#ifdef EINTR
case G_FILE_ERROR_INTR: return EINTR;
#endif
-#ifdef EWIO
+#ifdef EIO
case G_FILE_ERROR_IO: return EIO;
#endif
#ifdef EPERM
static gboolean
_wapi_lock_file_region (gint fd, off_t offset, off_t length)
{
-#if defined(__native_client__)
- printf("WARNING: %s: fcntl() not available on Native Client!\n", __func__);
- // behave as below -- locks are not available
- return TRUE;
-#else
struct flock lock_data;
gint ret;
}
return TRUE;
-#endif /* __native_client__ */
}
static gboolean
_wapi_unlock_file_region (gint fd, off_t offset, off_t length)
{
-#if defined(__native_client__)
- printf("WARNING: %s: fcntl() not available on Native Client!\n", __func__);
- return TRUE;
-#else
struct flock lock_data;
gint ret;
}
return TRUE;
-#endif /* __native_client__ */
}
-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)
-{
- MONO_REQ_GC_SAFE_MODE; /* FIXME: after mono_w32handle_close is coop-aware, change this to UNSAFE_MODE and 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);
#ifdef HAVE_LARGE_FILE_SUPPORT
if(highmovedistance==NULL) {
offset=movedistance;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting offset to %lld (low %d)", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting offset to %" G_GINT64_FORMAT " (low %" G_GINT32_FORMAT ")", __func__,
offset, movedistance);
} else {
offset=((gint64) *highmovedistance << 32) | (guint32)movedistance;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting offset to %lld 0x%llx (high %d 0x%x, low %d 0x%x)", __func__, offset, offset, *highmovedistance, *highmovedistance, movedistance, movedistance);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting offset to %" G_GINT64_FORMAT " 0x%" PRIx64 " (high %" G_GINT32_FORMAT " 0x%" PRIx32 ", low %" G_GINT32_FORMAT " 0x%" PRIx32 ")",
+ __func__, offset, offset, *highmovedistance, *highmovedistance, movedistance, movedistance);
}
#else
offset=movedistance;
#endif
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: moving handle %p by %lld bytes from %d", __func__,
- handle, (long long)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
+#ifdef HOST_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);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: lseek returns %lld", __func__, newpos);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: lseek returns %" G_GINT64_FORMAT, __func__, newpos);
#ifdef HAVE_LARGE_FILE_SUPPORT
ret=newpos & 0xFFFFFFFF;
}
#endif
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: move of handle %p returning %d/%d", __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);
}
#endif
-/* Native Client has no ftruncate function, even in standalone sel_ldr. */
-#ifndef __native_client__
/* always truncate, because the extend write() adds an extra
* byte to the end of the file
*/
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);
}
-#endif
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);
*highsize = bigsize>>32;
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning block device size %d/%d",
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning block device size %" G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT,
__func__, size, *highsize);
return(size);
size = statbuf.st_size;
#endif
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning size %d/%d", __func__, size, *highsize);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning size %" G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT, __func__, size, *highsize);
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);
access_ticks=((guint64)statbuf.st_atime*10000000)+116444736000000000ULL;
write_ticks=((guint64)statbuf.st_mtime*10000000)+116444736000000000ULL;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: aticks: %llu cticks: %llu wticks: %llu", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: aticks: %" G_GUINT64_FORMAT " cticks: %" G_GUINT64_FORMAT " wticks: %" G_GUINT64_FORMAT, __func__,
access_ticks, create_ticks, write_ticks);
if(create_time!=NULL) {
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)
-{
- MONO_REQ_GC_SAFE_MODE; /* FIXME: after mono_w32handle_close is coop-aware, change this to UNSAFE_MODE and 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)
-{
- MONO_REQ_GC_SAFE_MODE; /* FIXME: after mono_w32handle_close is coop-aware, change this to UNSAFE_MODE and 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 %d 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 %d 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);
}
flags=O_RDWR;
break;
default:
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unknown access type 0x%x", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unknown access type 0x%" PRIx32, __func__,
fileaccess);
break;
}
flags|=O_TRUNC;
break;
default:
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unknown create mode 0x%x", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unknown create mode 0x%" PRIx32, __func__,
createmode);
break;
}
*/
if (file_existing_share == 0) {
/* Quick and easy, no possibility to share */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%x, file has sharing = NONE", __func__, fileaccess);
+ 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);
}
((file_existing_share == FILE_SHARE_WRITE) &&
(fileaccess != GENERIC_WRITE))) {
/* New access mode doesn't match up */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%x, file has sharing: 0x%x", __func__, fileaccess, file_existing_share);
+ 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);
}
((file_existing_access & GENERIC_WRITE) &&
!(sharemode & FILE_SHARE_WRITE))) {
/* New share mode doesn't match up */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Access mode prevents open: requested share: 0x%x, file has access: 0x%x", __func__, sharemode, file_existing_access);
+ 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);
}
*/
if (file_existing_share == 0) {
/* Quick and easy, no possibility to share */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%x, file has sharing = NONE", __func__, (*share_info)->access);
+ 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);
}
if (!(file_existing_share & FILE_SHARE_DELETE)) {
/* New access mode doesn't match up */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Share mode prevents open: requested access: 0x%x, file has sharing: 0x%x", __func__, (*share_info)->access, file_existing_share);
+ 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)
return(INVALID_HANDLE_VALUE);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening %s with share 0x%x and access 0x%x", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening %s with share 0x%" PRIx32 " and access 0x%" PRIx32, __func__,
filename, sharemode, fileaccess);
fd = _wapi_open (filename, flags, perms);
if (fd == -1 && errno == EISDIR)
{
/* Try again but don't try to make it writable */
- fd = _wapi_open (filename, flags & ~(O_RDWR|O_WRONLY), perms);
- }
-
- if (fd == -1) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Error opening file %s: %s", __func__, filename,
- 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;
+ fd = _wapi_open (filename, flags & ~(O_RDWR|O_WRONLY), perms);
+ }
+
+ if (fd == -1) {
+ 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);
}
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);
}
-#ifdef __native_client__
- /* Workaround: Native Client currently returns the same fake inode
- * for all files, so do a simple hash on the filename so we don't
- * use the same share info for each file.
- */
- statbuf.st_ino = g_str_hash(filename);
+
+#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, sharemode, fileaccess,
- &file_handle.share_info) == FALSE) {
+ if (!share_allows_open (&statbuf, filehandle->sharemode, filehandle->fileaccess, &filehandle->share_info)) {
mono_w32error_set_last (ERROR_SHARING_VIOLATION);
- g_free (filename);
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)
gchar *filename;
gint retval;
gboolean ret = FALSE;
- guint32 attrs;
#if 0
struct stat statbuf;
FileShare *shareinfo;
return(FALSE);
}
- attrs = mono_w32file_get_attributes (name);
- if (attrs == INVALID_FILE_ATTRIBUTES) {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: file attributes error", __func__);
- /* Error set by mono_w32file_get_attributes() */
- g_free (filename);
- return(FALSE);
- }
-
#if 0
/* Check to make sure sharing allows us to open the file for
* writing. See bug 323389.
retval = _wapi_unlink (filename);
if (retval == -1) {
+ /* On linux, calling unlink on an non-existing file in a read-only mount will fail with EROFS.
+ * The expected behavior is for this function to return FALSE and not trigger an exception.
+ * To work around this behavior, we stat the file on failure.
+ *
+ * This was supposedly fixed on kernel 3.0 [1] but we could reproduce it with Ubuntu 16.04 which has kernel 4.4.
+ * We can't remove this workaround until the early 2020's when most Android deviced will have a fix.
+ * [1] https://github.com/torvalds/linux/commit/50338b889dc504c69e0cb316ac92d1b9e51f3c8a
+ */
+ if (errno == EROFS) {
+ MonoIOStat stat;
+ if (mono_w32file_get_attributes_ex (name, &stat)) //The file exists, so must be due the RO file system
+ errno = EROFS;
+ }
_wapi_set_last_path_error_from_errno (NULL, filename);
} else {
ret = TRUE;
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);
-#if !defined(__native_client__)
/* Check if fd is valid */
do {
flags = fcntl(fd, F_GETFL);
/* 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;
}
-#else
- /*
- * fcntl will return -1 in nacl, as there is no real file system API.
- * Yet, standard streams are available.
- */
- file_handle.fileaccess = (fd == STDIN_FILENO) ? GENERIC_READ : GENERIC_WRITE;
-#endif
- 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);
+ if (!mono_fdhandle_lookup_and_ref(fd, (MonoFDHandle**) &filehandle)) {
+ gpointer handle;
- mono_coop_mutex_lock (&stdhandle_mutex);
-
- 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;
}
- } else {
- /* Add a reference to this handle */
- mono_w32handle_ref (handle);
}
-
- 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,
totaldays=(file_ticks / TICKS_PER_DAY);
rem = file_ticks % TICKS_PER_DAY;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %lld rem: %lld", __func__, totaldays, rem);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %" G_GINT64_FORMAT " rem: %" G_GINT64_FORMAT, __func__,
+ totaldays, rem);
system_time->wHour=rem/TICKS_PER_HOUR;
rem %= TICKS_PER_HOUR;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hour: %d rem: %lld", __func__, system_time->wHour, rem);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Hour: %d rem: %" G_GINT64_FORMAT, __func__,
+ system_time->wHour, rem);
system_time->wMinute = rem / TICKS_PER_MINUTE;
rem %= TICKS_PER_MINUTE;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Minute: %d rem: %lld", __func__, system_time->wMinute,
- rem);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Minute: %d rem: %" G_GINT64_FORMAT, __func__,
+ system_time->wMinute, rem);
system_time->wSecond = rem / TICKS_PER_SECOND;
rem %= TICKS_PER_SECOND;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Second: %d rem: %lld", __func__, system_time->wSecond,
- rem);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Second: %d rem: %" G_GINT64_FORMAT, __func__,
+ system_time->wSecond, rem);
system_time->wMilliseconds = rem / TICKS_PER_MILLISECOND;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Milliseconds: %d", __func__,
while(totaldays < 0 || totaldays >= (isleap(y)?366:365)) {
/* Guess a corrected year, assuming 365 days per year */
gint64 yg = y + totaldays / 365 - (totaldays % 365 < 0);
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %lld yg: %lld y: %lld", __func__,
- totaldays, yg,
- y);
- g_message("%s: LEAPS(yg): %lld LEAPS(y): %lld", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %" G_GINT64_FORMAT " yg: %" G_GINT64_FORMAT " y: %" G_GINT64_FORMAT, __func__,
+ totaldays, yg, y);
+ g_message("%s: LEAPS(yg): %li LEAPS(y): %li", __func__,
LEAPS_THRU_END_OF(yg-1), LEAPS_THRU_END_OF(y-1));
/* Adjust days and y to match the guessed year. */
totaldays -= ((yg - y) * 365
+ LEAPS_THRU_END_OF (yg - 1)
- LEAPS_THRU_END_OF (y - 1));
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %lld", __func__, totaldays);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %" G_GINT64_FORMAT,
+ __func__, totaldays);
y = yg;
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: y: %lld", __func__, y);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: y: %" G_GINT64_FORMAT, __func__, y);
}
system_time->wYear = y;
continue;
}
totaldays-=ip[y];
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %lld", __func__, totaldays);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: totaldays: %" G_GINT64_FORMAT, __func__, totaldays);
system_time->wMonth = y + 1;
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Month: %d", __func__, system_time->wMonth);
goto retry;
}
-#ifndef __native_client__
result = _wapi_lstat (filename, &linkbuf);
if (result != 0) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: lstat failed: %s", __func__, filename);
g_free (filename);
goto retry;
}
-#endif
utf8_filename = mono_utf8_from_external (filename);
if (utf8_filename == NULL) {
else
create_time = buf.st_ctime;
-#ifdef __native_client__
- find_data->dwFileAttributes = _wapi_stat_to_file_attributes (utf8_filename, &buf, NULL);
-#else
find_data->dwFileAttributes = _wapi_stat_to_file_attributes (utf8_filename, &buf, &linkbuf);
-#endif
time_t_to_filetime (create_time, &find_data->ftCreationTime);
time_t_to_filetime (buf.st_atime, &find_data->ftLastAccessTime);
mono_w32handle_unlock_handle (handle);
- mono_w32handle_unref (handle);
+ MONO_ENTER_GC_SAFE;
+ mono_w32handle_close (handle);
+ MONO_EXIT_GC_SAFE;
return(TRUE);
}
}
result = _wapi_stat (utf8_name, &buf);
- if (result == -1 && errno == ENOENT) {
+ if (result == -1 && (errno == ENOENT || errno == ELOOP)) {
/* Might be a dangling symlink... */
result = _wapi_lstat (utf8_name, &buf);
}
return (INVALID_FILE_ATTRIBUTES);
}
-#ifndef __native_client__
result = _wapi_lstat (utf8_name, &linkbuf);
if (result != 0) {
_wapi_set_last_path_error_from_errno (NULL, utf8_name);
g_free (utf8_name);
return (INVALID_FILE_ATTRIBUTES);
}
-#endif
-#ifdef __native_client__
- ret = _wapi_stat_to_file_attributes (utf8_name, &buf, NULL);
-#else
ret = _wapi_stat_to_file_attributes (utf8_name, &buf, &linkbuf);
-#endif
g_free (utf8_name);
glong count;
gsize bytes;
-#ifdef __native_client__
- gchar *path = g_get_current_dir ();
- if (length < strlen(path) + 1 || path == NULL)
- return 0;
- memcpy (buffer, path, strlen(path) + 1);
-#else
if (getcwd ((gchar*)buffer, length) == NULL) {
if (errno == ERANGE) { /*buffer length is not big enough */
gchar *path = g_get_current_dir (); /*FIXME g_get_current_dir doesn't work with broken paths and calling it just to know the path length is silly*/
_wapi_set_last_error_from_errno ();
return 0;
}
-#endif
utf16_path = mono_unicode_from_external ((gchar*)buffer, &bytes);
count = (bytes/2)+1;
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__);
- mono_w32handle_unref (read_handle);
-
- MONO_ENTER_GC_SAFE;
- 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;
+ read_filehandle = file_data_create (MONO_FDTYPE_PIPE, filedes[0]);
+ read_filehandle->fileaccess = GENERIC_READ;
+
+ 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);
}
} _wapi_drive_type;
static _wapi_drive_type _wapi_drive_types[] = {
-#if PLATFORM_MACOSX
+#if HOST_DARWIN
{ DRIVE_REMOTE, "afp" },
{ DRIVE_REMOTE, "autofs" },
{ DRIVE_CDROM, "cddafs" },
{ DRIVE_RAMDISK, "fdesc" },
{ DRIVE_REMOTE, "ftp" },
{ DRIVE_FIXED, "hfs" },
+ { DRIVE_FIXED, "apfs" },
+ { DRIVE_REMOTE, "kbfuse" },
{ DRIVE_FIXED, "msdos" },
{ DRIVE_REMOTE, "nfs" },
{ DRIVE_FIXED, "ntfs" },
}
#endif
-#if defined (PLATFORM_MACOSX) || defined (__linux__)
+#if defined (HOST_DARWIN) || defined (__linux__)
static guint32
GetDriveTypeFromPath (const gchar *utf8_root_path_name)
{
MONO_EXIT_GC_SAFE;
if (res == -1)
return DRIVE_UNKNOWN;
-#if PLATFORM_MACOSX
+#if HOST_DARWIN
return _wapi_get_drive_type (buf.f_fstypename);
#else
return _wapi_get_drive_type (buf.f_type);
return (drive_type);
}
-#if defined (PLATFORM_MACOSX) || defined (__linux__) || defined(PLATFORM_BSD) || defined(__native_client__) || defined(__FreeBSD_kernel__)
+#if defined (HOST_DARWIN) || defined (__linux__) || defined(HOST_BSD) || defined(__FreeBSD_kernel__) || defined(__HAIKU__)
static gchar*
get_fstypename (gchar *utfpath)
{
-#if defined (PLATFORM_MACOSX) || defined (__linux__)
+#if defined (HOST_DARWIN) || defined (__linux__)
struct statfs stat;
#if __linux__
_wapi_drive_type *current;
MONO_EXIT_GC_SAFE;
if (statfs_res == -1)
return NULL;
-#if PLATFORM_MACOSX
+#if HOST_DARWIN
return g_strdup (stat.f_fstypename);
#else
current = &_wapi_drive_types[0];
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 %lld, length %lld", __func__, handle, offset, 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 %ld, length %ld", __func__, handle, offset, 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 (((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: Unlocking handle %p, offset %lld, length %lld", __func__, handle, offset, 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 %ld, length %ld", __func__, handle, offset, 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_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_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_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_getenv ("MONO_STRICT_IO_EMULATION"))
+ if (g_hasenv ("MONO_STRICT_IO_EMULATION"))
lock_while_writing = TRUE;
}