+/**
+ * \file
+ */
#include <config.h>
#include <glib.h>
#include "w32file-unix-glob.h"
#include "w32handle.h"
+#include "w32error.h"
#include "utils/mono-io-portability.h"
#include "utils/mono-logger-internals.h"
#include "utils/mono-os-mutex.h"
typedef struct {
guint64 device;
guint64 inode;
- pid_t opened_by_pid;
guint32 sharemode;
guint32 access;
guint32 handle_refs;
* 4MB array.
*/
static GHashTable *file_share_table;
-static mono_mutex_t file_share_mutex;
+static MonoCoopMutex file_share_mutex;
static void
time_t_to_filetime (time_t timeval, FILETIME *filetime)
file_share_release (FileShare *share_info)
{
/* Prevent new entries racing with us */
- mono_os_mutex_lock (&file_share_mutex);
+ mono_coop_mutex_lock (&file_share_mutex);
g_assert (share_info->handle_refs > 0);
share_info->handle_refs -= 1;
if (share_info->handle_refs == 0)
g_hash_table_remove (file_share_table, share_info);
- mono_os_mutex_unlock (&file_share_mutex);
+ mono_coop_mutex_unlock (&file_share_mutex);
}
static gint
gboolean exists = FALSE;
/* Prevent new entries racing with us */
- mono_os_mutex_lock (&file_share_mutex);
+ mono_coop_mutex_lock (&file_share_mutex);
FileShare tmp;
file_share->device = device;
file_share->inode = inode;
- file_share->opened_by_pid = wapi_getpid ();
file_share->sharemode = new_sharemode;
file_share->access = new_access;
file_share->handle_refs = 1;
g_hash_table_insert (file_share_table, file_share, file_share);
}
- mono_os_mutex_unlock (&file_share_mutex);
+ mono_coop_mutex_unlock (&file_share_mutex);
return(exists);
}
if (flags & O_CREAT) {
located_filename = mono_portability_find_file (pathname, FALSE);
if (located_filename == NULL) {
+ MONO_ENTER_GC_SAFE;
fd = open (pathname, flags, mode);
+ MONO_EXIT_GC_SAFE;
} else {
+ MONO_ENTER_GC_SAFE;
fd = open (located_filename, flags, mode);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
} else {
+ MONO_ENTER_GC_SAFE;
fd = open (pathname, flags, mode);
+ MONO_EXIT_GC_SAFE;
if (fd == -1 && (errno == ENOENT || errno == ENOTDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
located_filename = mono_portability_find_file (pathname, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
fd = open (located_filename, flags, mode);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = access (pathname, mode);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (pathname, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = access (located_filename, mode);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = chmod (pathname, mode);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (pathname, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = chmod (located_filename, mode);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = utime (filename, buf);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && errno == ENOENT && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (filename, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = utime (located_filename, buf);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = unlink (pathname);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR || errno == EISDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (pathname, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = unlink (located_filename);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
gchar *located_newpath = mono_portability_find_file (newpath, FALSE);
if (located_newpath == NULL) {
+ MONO_ENTER_GC_SAFE;
ret = rename (oldpath, newpath);
+ MONO_EXIT_GC_SAFE;
} else {
+ MONO_ENTER_GC_SAFE;
ret = rename (oldpath, located_newpath);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == EISDIR || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EXDEV) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = rename (located_oldpath, located_newpath);
+ MONO_EXIT_GC_SAFE;
g_free (located_oldpath);
}
g_free (located_newpath);
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = stat (path, buf);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (path, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = stat (located_filename, buf);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = lstat (path, buf);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (path, TRUE);
gchar *located_filename = mono_portability_find_file (pathname, FALSE);
if (located_filename == NULL) {
+ MONO_ENTER_GC_SAFE;
ret = mkdir (pathname, mode);
+ MONO_EXIT_GC_SAFE;
} else {
+ MONO_ENTER_GC_SAFE;
ret = mkdir (located_filename, mode);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = rmdir (pathname);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (pathname, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = rmdir (located_filename);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
gint ret;
+ MONO_ENTER_GC_SAFE;
ret = chdir (path);
+ MONO_EXIT_GC_SAFE;
if (ret == -1 && (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) && IS_PORTABILITY_SET) {
gint saved_errno = errno;
gchar *located_filename = mono_portability_find_file (path, TRUE);
return -1;
}
+ MONO_ENTER_GC_SAFE;
ret = chdir (located_filename);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
}
{
GDir *ret;
+ MONO_ENTER_GC_SAFE;
ret = g_dir_open (path, flags, error);
+ MONO_EXIT_GC_SAFE;
if (ret == NULL && ((*error)->code == G_FILE_ERROR_NOENT || (*error)->code == G_FILE_ERROR_NOTDIR || (*error)->code == G_FILE_ERROR_NAMETOOLONG) && IS_PORTABILITY_SET) {
gchar *located_filename = mono_portability_find_file (path, TRUE);
GError *tmp_error = NULL;
return(NULL);
}
+ MONO_ENTER_GC_SAFE;
ret = g_dir_open (located_filename, flags, &tmp_error);
+ MONO_EXIT_GC_SAFE;
g_free (located_filename);
if (tmp_error == NULL) {
g_clear_error (error);
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
gchar *pattern2 = g_strndup (pattern, strlen (pattern) - 2);
gint result2;
+ MONO_ENTER_GC_SAFE;
g_dir_rewind (dir);
+ MONO_EXIT_GC_SAFE;
result2 = mono_w32file_unix_glob (dir, pattern2, flags | W32FILE_UNIX_GLOB_APPEND | W32FILE_UNIX_GLOB_UNIQUE, &glob_buf);
g_free (pattern2);
}
}
+ MONO_ENTER_GC_SAFE;
g_dir_close (dir);
+ MONO_EXIT_GC_SAFE;
if (glob_buf.gl_pathc == 0) {
return(0);
} else if (result != 0) {
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;
if (offset < 0 || length < 0) {
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
- SetLastError (ERROR_LOCK_VIOLATION);
+ mono_w32error_set_last (ERROR_LOCK_VIOLATION);
return FALSE;
}
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;
}
- SetLastError (ERROR_LOCK_VIOLATION);
+ mono_w32error_set_last (ERROR_LOCK_VIOLATION);
return FALSE;
}
return TRUE;
-#endif /* __native_client__ */
}
static void file_close (gpointer handle, gpointer data);
static void
_wapi_set_last_error_from_errno (void)
{
- SetLastError (_wapi_get_win32_file_error (errno));
+ mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
}
static void _wapi_set_last_path_error_from_errno (const gchar *dir,
}
if (_wapi_access (dirname, F_OK) == 0) {
- SetLastError (ERROR_FILE_NOT_FOUND);
+ mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
} else {
- SetLastError (ERROR_PATH_NOT_FOUND);
+ mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
}
g_free (dirname);
*/
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;
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)
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
do {
+ MONO_ENTER_GC_SAFE;
ret = read (fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of handle %p error: %s", __func__,
handle, strerror(err));
- SetLastError (_wapi_get_win32_file_error (err));
+ mono_w32error_set_last (mono_w32error_unix_to_win32 (err));
return(FALSE);
}
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
* because we only do advisory locking on POSIX
* systems
*/
+ MONO_ENTER_GC_SAFE;
current_pos = lseek (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));
}
do {
+ MONO_ENTER_GC_SAFE;
ret = write (fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
+ MONO_ENTER_GC_SAFE;
ret=fsync(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));
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(INVALID_SET_FILE_POINTER);
}
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(INVALID_SET_FILE_POINTER);
}
default:
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: invalid seek type %d", __func__, method);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(INVALID_SET_FILE_POINTER);
}
#ifdef PLATFORM_ANDROID
/* bionic doesn't support -D_FILE_OFFSET_BITS=64 */
+ MONO_ENTER_GC_SAFE;
newpos=lseek64(fd, offset, whence);
+ MONO_EXIT_GC_SAFE;
#else
+ MONO_ENTER_GC_SAFE;
newpos=lseek(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",
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = file_handle->fd;
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
* than the length, truncate the file.
*/
+ 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: handle %p fstat failed: %s", __func__,
handle, strerror(errno));
return(FALSE);
}
+ MONO_ENTER_GC_SAFE;
pos=lseek(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));
* drop this write.
*/
do {
+ MONO_ENTER_GC_SAFE;
ret = write (fd, "", 1);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
}
/* And put the file position back after the write */
+ MONO_ENTER_GC_SAFE;
ret = lseek (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));
}
#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);
+ MONO_EXIT_GC_SAFE;
}
while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
_wapi_set_last_error_from_errno ();
return(FALSE);
}
-#endif
return(TRUE);
}
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(INVALID_FILE_SIZE);
}
fd = file_handle->fd;
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(INVALID_FILE_SIZE);
}
* caller can't tell if this is an error, so clear the error
* value
*/
- SetLastError (ERROR_SUCCESS);
+ mono_w32error_set_last (ERROR_SUCCESS);
+ 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: handle %p fstat failed: %s", __func__,
handle, strerror(errno));
#ifdef BLKGETSIZE64
if (S_ISBLK(statbuf.st_mode)) {
guint64 bigsize;
- if (ioctl(fd, BLKGETSIZE64, &bigsize) < 0) {
+ gint res;
+ MONO_ENTER_GC_SAFE;
+ res = ioctl (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));
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = file_handle->fd;
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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
+ 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: handle %p fstat failed: %s", __func__, handle,
strerror(errno));
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = file_handle->fd;
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ 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);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
/* Get the current times, so we can put the same times back in
* the event that one of the FileTime structs is NULL
*/
+ 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: handle %p fstat failed: %s", __func__, handle,
strerror(errno));
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (access_ticks < 116444736000000000ULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt to set access time too early",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (sizeof (utbuf.actime) == 4 && ((access_ticks - 116444736000000000ULL) / 10000000) > INT_MAX) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt to set write time that is too big for a 32bits time_t",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (write_ticks < 116444736000000000ULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt to set write time too early",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (sizeof (utbuf.modtime) == 4 && ((write_ticks - 116444736000000000ULL) / 10000000) > INT_MAX) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt to set write time that is too big for a 32bits time_t",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p [%s] utime failed: %s", __func__,
handle, file_handle->filename, strerror(errno));
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
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;
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)
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = console_handle->fd;
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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
do {
+ MONO_ENTER_GC_SAFE;
ret=read(fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = console_handle->fd;
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
do {
+ MONO_ENTER_GC_SAFE;
ret = write(fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
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;
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)
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = pipe_handle->fd;
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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
numbytes, handle);
do {
+ MONO_ENTER_GC_SAFE;
ret=read(fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
fd = pipe_handle->fd;
!(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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return(FALSE);
}
handle);
do {
+ MONO_ENTER_GC_SAFE;
ret = write (fd, buffer, numbytes);
+ MONO_EXIT_GC_SAFE;
} while (ret == -1 && errno == EINTR &&
!mono_thread_info_is_interrupt_state (info));
perms = 0600;
if (attrs & FILE_ATTRIBUTE_ENCRYPTED){
- SetLastError (ERROR_ENCRYPTION_FAILED);
+ mono_w32error_set_last (ERROR_ENCRYPTION_FAILED);
return INVALID_HANDLE_VALUE;
}
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
if (filename == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
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__);
- SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+ 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));
_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);
-#endif
if (share_allows_open (&statbuf, sharemode, fileaccess,
&file_handle.share_info) == FALSE) {
- SetLastError (ERROR_SHARING_VIOLATION);
+ mono_w32error_set_last (ERROR_SHARING_VIOLATION);
g_free (filename);
+ MONO_ENTER_GC_SAFE;
close (fd);
+ MONO_EXIT_GC_SAFE;
return (INVALID_HANDLE_VALUE);
}
/* 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__);
- SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+ 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);
file_handle.attrs=attrs;
#ifdef HAVE_POSIX_FADVISE
- if (attrs & FILE_FLAG_SEQUENTIAL_SCAN)
+ if (attrs & FILE_FLAG_SEQUENTIAL_SCAN) {
+ MONO_ENTER_GC_SAFE;
posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
- if (attrs & FILE_FLAG_RANDOM_ACCESS)
+ MONO_EXIT_GC_SAFE;
+ }
+ if (attrs & FILE_FLAG_RANDOM_ACCESS) {
+ MONO_ENTER_GC_SAFE;
posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM);
+ MONO_EXIT_GC_SAFE;
+ }
#endif
#ifdef F_RDAHEAD
- if (attrs & FILE_FLAG_SEQUENTIAL_SCAN)
+ if (attrs & FILE_FLAG_SEQUENTIAL_SCAN) {
+ MONO_ENTER_GC_SAFE;
fcntl(fd, F_RDAHEAD, 1);
+ MONO_EXIT_GC_SAFE;
+ }
#endif
#ifndef S_ISFIFO
handle_type = MONO_W32HANDLE_FILE;
}
+ 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;
- SetLastError (ERROR_GEN_FAILURE);
+ mono_w32error_set_last (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
}
return(handle);
}
+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;
+}
+
gboolean mono_w32file_delete(const gunichar2 *name)
{
gchar *filename;
gint retval;
gboolean ret = FALSE;
- guint32 attrs;
#if 0
struct stat statbuf;
FileShare *shareinfo;
if(name==NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if(filename==NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
- 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);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (share_allows_open (&statbuf, 0, GENERIC_WRITE,
&shareinfo) == FALSE) {
- SetLastError (ERROR_SHARING_VIOLATION);
+ mono_w32error_set_last (ERROR_SHARING_VIOLATION);
g_free (filename);
return FALSE;
}
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;
if(name==NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return FALSE;
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
g_free (utf8_name);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
g_free (utf8_name);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return FALSE;
}
stat_dest.st_ino != stat_src.st_ino) {
g_free (utf8_name);
g_free (utf8_dest_name);
- SetLastError (ERROR_ALREADY_EXISTS);
+ mono_w32error_set_last (ERROR_ALREADY_EXISTS);
return FALSE;
}
}
* then we can implement that later.
*/
if (share_allows_delete (&stat_src, &shareinfo) == FALSE) {
- SetLastError (ERROR_SHARING_VIOLATION);
+ mono_w32error_set_last (ERROR_SHARING_VIOLATION);
return FALSE;
}
if (shareinfo)
if (result == -1) {
switch(errno_copy) {
case EEXIST:
- SetLastError (ERROR_ALREADY_EXISTS);
+ mono_w32error_set_last (ERROR_ALREADY_EXISTS);
break;
case EXDEV:
gint32 copy_error;
if (S_ISDIR (stat_src.st_mode)) {
- SetLastError (ERROR_NOT_SAME_DEVICE);
+ mono_w32error_set_last (ERROR_NOT_SAME_DEVICE);
return FALSE;
}
/* Try a copy to the new location, and delete the source */
buf = (gchar *) g_malloc (buf_size);
for (;;) {
+ MONO_ENTER_GC_SAFE;
remain = read (src_fd, buf, buf_size);
+ MONO_EXIT_GC_SAFE;
if (remain < 0) {
if (errno == EINTR && !mono_thread_info_is_interrupt_state (info))
continue;
wbuf = buf;
while (remain > 0) {
- if ((n = write (dest_fd, wbuf, remain)) < 0) {
+ MONO_ENTER_GC_SAFE;
+ n = write (dest_fd, wbuf, remain);
+ MONO_EXIT_GC_SAFE;
+ if (n < 0) {
if (errno == EINTR && !mono_thread_info_is_interrupt_state (info))
continue;
struct utimbuf dest_time;
gboolean ret = TRUE;
gint ret_utime;
+ gint syscall_res;
if(name==NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion of source returned NULL",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: dest is NULL", __func__);
g_free (utf8_src);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion of dest returned NULL",
__func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
g_free (utf8_src);
return(FALSE);
}
- if (fstat (src_fd, &st) < 0) {
+ MONO_ENTER_GC_SAFE;
+ syscall_res = fstat (src_fd, &st);
+ MONO_EXIT_GC_SAFE;
+ if (syscall_res < 0) {
_wapi_set_last_error_from_errno ();
g_free (utf8_src);
g_free (utf8_dest);
+ MONO_ENTER_GC_SAFE;
close (src_fd);
+ MONO_EXIT_GC_SAFE;
return(FALSE);
}
g_free (utf8_src);
g_free (utf8_dest);
+ MONO_ENTER_GC_SAFE;
close (src_fd);
+ MONO_EXIT_GC_SAFE;
- SetLastError (ERROR_SHARING_VIOLATION);
+ mono_w32error_set_last (ERROR_SHARING_VIOLATION);
return (FALSE);
}
dest_fd = _wapi_open (utf8_dest, O_WRONLY | O_CREAT | O_EXCL, st.st_mode);
} else {
/* FIXME: it kinda sucks that this code path potentially scans
- * the directory twice due to the weird SetLastError()
+ * the directory twice due to the weird mono_w32error_set_last()
* behavior. */
dest_fd = _wapi_open (utf8_dest, O_WRONLY | O_TRUNC, st.st_mode);
if (dest_fd < 0) {
/* Apparently this error is set if we
* overwrite the dest file
*/
- SetLastError (ERROR_ALREADY_EXISTS);
+ mono_w32error_set_last (ERROR_ALREADY_EXISTS);
}
}
if (dest_fd < 0) {
g_free (utf8_src);
g_free (utf8_dest);
+ MONO_ENTER_GC_SAFE;
close (src_fd);
+ MONO_EXIT_GC_SAFE;
return(FALSE);
}
dest_time.modtime = st.st_mtime;
dest_time.actime = st.st_atime;
+ MONO_ENTER_GC_SAFE;
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));
if (arg == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s is NULL", __func__, arg_name);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return NULL;
}
if (utf8_ret == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion of %s returned NULL",
__func__, arg_name);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return NULL;
}
g_free (utf8_replacedFileName);
g_free (utf8_replacementFileName);
g_free (utf8_backupFileName);
- if (backup_fd != -1)
+ if (backup_fd != -1) {
+ MONO_ENTER_GC_SAFE;
close (backup_fd);
- if (replaced_fd != -1)
+ MONO_EXIT_GC_SAFE;
+ }
+ if (replaced_fd != -1) {
+ MONO_ENTER_GC_SAFE;
close (replaced_fd);
+ MONO_EXIT_GC_SAFE;
+ }
return ret;
}
-static mono_mutex_t stdhandle_mutex;
+static MonoCoopMutex stdhandle_mutex;
static gpointer
_wapi_stdhandle_create (gint fd, const gchar *name)
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);
*/
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fcntl error on fd %d: %s", __func__, fd, strerror(errno));
- SetLastError (_wapi_get_win32_file_error (errno));
+ mono_w32error_set_last (mono_w32error_unix_to_win32 (errno));
return INVALID_HANDLE_VALUE;
}
file_handle.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);
handle = mono_w32handle_new_fd (MONO_W32HANDLE_CONSOLE, fd, &file_handle);
if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating file handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
+ mono_w32error_set_last (ERROR_GEN_FAILURE);
return INVALID_HANDLE_VALUE;
}
handle = GINT_TO_POINTER (fd);
- mono_os_mutex_lock (&stdhandle_mutex);
+ mono_coop_mutex_lock (&stdhandle_mutex);
ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&file_handle);
handle = _wapi_stdhandle_create (fd, name);
if (handle == INVALID_HANDLE_VALUE) {
- SetLastError (ERROR_NO_MORE_FILES);
+ mono_w32error_set_last (ERROR_NO_MORE_FILES);
goto done;
}
- } else {
- /* Add a reference to this handle */
- mono_w32handle_ref (handle);
}
done:
- mono_os_mutex_unlock (&stdhandle_mutex);
-
+ mono_coop_mutex_unlock (&stdhandle_mutex);
+
return(handle);
}
type = mono_w32handle_get_type (handle);
if(io_ops[type].readfile==NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
type = mono_w32handle_get_type (handle);
if(io_ops[type].writefile==NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
type = mono_w32handle_get_type (handle);
if(io_ops[type].flushfile==NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].setendoffile == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].seek == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(INVALID_SET_FILE_POINTER);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletype == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FILE_TYPE_UNKNOWN);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].getfilesize == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(INVALID_FILE_SIZE);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletime == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
type = mono_w32handle_get_type (handle);
if (io_ops[type].setfiletime == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
if(system_time==NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: system_time NULL", __func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if(file_ticks<0) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: file_time too big", __func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if (pattern == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pattern is NULL", __func__);
- SetLastError (ERROR_PATH_NOT_FOUND);
+ mono_w32error_set_last (ERROR_PATH_NOT_FOUND);
return(INVALID_HANDLE_VALUE);
}
if (utf8_pattern == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
* FIXME: Figure out a better solution to keep some checks...
*/
if (strchr (dir_part, '*') || strchr (dir_part, '?')) {
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
g_free (dir_part);
g_free (entry_part);
g_free (utf8_pattern);
/* No files, which windows seems to call
* FILE_NOT_FOUND
*/
- SetLastError (ERROR_FILE_NOT_FOUND);
+ mono_w32error_set_last (ERROR_FILE_NOT_FOUND);
g_free (utf8_pattern);
g_free (entry_part);
g_free (dir_part);
g_free (dir_part);
g_free (entry_part);
g_free (utf8_pattern);
- SetLastError (ERROR_GEN_FAILURE);
+ mono_w32error_set_last (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
}
if (handle != INVALID_HANDLE_VALUE &&
!mono_w32file_find_next (handle, find_data)) {
mono_w32file_find_close (handle);
- SetLastError (ERROR_NO_MORE_FILES);
+ mono_w32error_set_last (ERROR_NO_MORE_FILES);
handle = INVALID_HANDLE_VALUE;
}
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
retry:
if (find_handle->count >= find_handle->num) {
- SetLastError (ERROR_NO_MORE_FILES);
+ mono_w32error_set_last (ERROR_NO_MORE_FILES);
goto cleanup;
}
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);
gboolean ok;
if (handle == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ mono_w32error_set_last (ERROR_INVALID_HANDLE);
return(FALSE);
}
mono_w32handle_unlock_handle (handle);
+ MONO_ENTER_GC_SAFE;
mono_w32handle_unref (handle);
+ MONO_EXIT_GC_SAFE;
return(TRUE);
}
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return FALSE;
}
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return FALSE;
}
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return (INVALID_FILE_ATTRIBUTES);
}
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);
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return FALSE;
}
if (name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
if (utf8_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return FALSE;
}
if ((buf.st_mode & S_IROTH) != 0)
exec_mask |= S_IXOTH;
+ MONO_ENTER_GC_SAFE;
result = chmod (utf8_name, buf.st_mode | exec_mask);
+ MONO_EXIT_GC_SAFE;
}
/* Don't bother to reset executable (might need to change this
* policy)
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 result;
if (path == NULL) {
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return(FALSE);
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating pipe", __func__);
+ 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));
filedes[1] >= mono_w32handle_fd_reserve) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
- SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+ 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);
}
&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]);
- SetLastError (ERROR_GEN_FAILURE);
+ MONO_EXIT_GC_SAFE;
+ mono_w32error_set_last (ERROR_GEN_FAILURE);
return(FALSE);
}
&pipe_write_handle);
if (write_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating pipe write handle", __func__);
+
+ MONO_ENTER_GC_SAFE;
mono_w32handle_unref (read_handle);
close (filedes[0]);
close (filedes[1]);
- SetLastError (ERROR_GEN_FAILURE);
+ MONO_EXIT_GC_SAFE;
+ mono_w32error_set_last (ERROR_GEN_FAILURE);
return(FALSE);
}
gint size, n, i;
gunichar2 *dir;
glong length, total = 0;
-
+ gint syscall_res;
+
+ MONO_ENTER_GC_SAFE;
n = getfsstat (NULL, 0, MNT_NOWAIT);
+ MONO_EXIT_GC_SAFE;
if (n == -1)
return 0;
size = n * sizeof (struct statfs);
stats = (struct statfs *) g_malloc (size);
if (stats == NULL)
return 0;
- if (getfsstat (stats, size, MNT_NOWAIT) == -1){
+ MONO_ENTER_GC_SAFE;
+ syscall_res = getfsstat (stats, size, MNT_NOWAIT);
+ MONO_EXIT_GC_SAFE;
+ if (syscall_res == -1){
g_free (stats);
return 0;
}
gboolean (*parser)(guint32, gunichar2*, LinuxMountInfoParseState*) = NULL;
memset (buf, 0, len * sizeof (gunichar2));
+ MONO_ENTER_GC_SAFE;
fd = open ("/proc/self/mountinfo", O_RDONLY);
+ MONO_EXIT_GC_SAFE;
if (fd != -1)
parser = GetLogicalDriveStrings_MountInfo;
else {
+ MONO_ENTER_GC_SAFE;
fd = open ("/proc/mounts", O_RDONLY);
+ MONO_EXIT_GC_SAFE;
if (fd != -1)
parser = GetLogicalDriveStrings_Mounts;
}
state.field_number = 1;
state.delimiter = ' ';
- while ((state.nbytes = read (fd, state.buffer, GET_LOGICAL_DRIVE_STRINGS_BUFFER)) > 0) {
+ while (1) {
+ MONO_ENTER_GC_SAFE;
+ state.nbytes = read (fd, state.buffer, GET_LOGICAL_DRIVE_STRINGS_BUFFER);
+ MONO_EXIT_GC_SAFE;
+ if (!(state.nbytes > 0))
+ break;
state.buffer_index = 0;
while ((*parser)(len, buf, &state)) {
ret = state.total;
done_and_out:
- if (fd != -1)
+ if (fd != -1) {
+ MONO_ENTER_GC_SAFE;
close (fd);
+ MONO_EXIT_GC_SAFE;
+ }
return ret;
}
/* Sigh, mntent and friends don't work well.
* It stops on the first line that doesn't begin with a '/'.
* (linux 2.6.5, libc 2.3.2.ds1-12) - Gonz */
+ MONO_ENTER_GC_SAFE;
fp = fopen ("/etc/mtab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL) {
+ MONO_ENTER_GC_SAFE;
fp = fopen ("/etc/mnttab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL)
return 1;
}
ptr = buf;
- while (fgets (buffer, 512, fp) != NULL) {
+ while (1) {
+ gchar *fgets_res;
+ MONO_ENTER_GC_SAFE;
+ fgets_res = fgets (buffer, 512, fp);
+ MONO_EXIT_GC_SAFE;
+ if (!fgets_res)
+ break;
if (*buffer != '/')
continue;
dir = g_utf8_to_utf16 (*(splitted + 1), -1, NULL, &length, NULL);
g_strfreev (splitted);
if (total + length + 1 > len) {
+ MONO_ENTER_GC_SAFE;
fclose (fp);
+ MONO_EXIT_GC_SAFE;
g_free (dir);
return len * 2; /* guess */
}
total += length + 1;
}
+ MONO_ENTER_GC_SAFE;
fclose (fp);
+ MONO_EXIT_GC_SAFE;
return total;
/* Commented out, does not work with my mtab!!! - Gonz */
#ifdef NOTENABLED /* HAVE_MNTENT_H */
glong len, total = 0;
+ MONO_ENTER_GC_SAFE;
fp = setmntent ("/etc/mtab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL) {
+ MONO_ENTER_GC_SAFE;
fp = setmntent ("/etc/mnttab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL)
return;
}
ptr = buf;
- while ((mnt = getmntent (fp)) != NULL) {
+ while (1) {
+ MONO_ENTER_GC_SAFE;
+ mnt = getmntent (fp);
+ MONO_EXIT_GC_SAFE;
+ if (mnt == NULL)
+ break;
g_print ("GOT %s\n", mnt->mnt_dir);
dir = g_utf8_to_utf16 (mnt->mnt_dir, &len, NULL, NULL, NULL);
if (total + len + 1 > len) {
+ MONO_ENTER_GC_SAFE;
+ endmntent (fp);
+ MONO_EXIT_GC_SAFE;
return len * 2; /* guess */
}
total += len + 1;
}
+ MONO_ENTER_GC_SAFE;
endmntent (fp);
+ MONO_EXIT_GC_SAFE;
return total;
}
#endif
if (path_name == NULL) {
utf8_path_name = g_strdup (g_get_current_dir());
if (utf8_path_name == NULL) {
- SetLastError (ERROR_DIRECTORY);
+ mono_w32error_set_last (ERROR_DIRECTORY);
return(FALSE);
}
}
if (utf8_path_name == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unicode conversion returned NULL", __func__);
- SetLastError (ERROR_INVALID_NAME);
+ mono_w32error_set_last (ERROR_INVALID_NAME);
return(FALSE);
}
}
do {
#ifdef HAVE_STATVFS
+ MONO_ENTER_GC_SAFE;
ret = statvfs (utf8_path_name, &fsstat);
+ MONO_EXIT_GC_SAFE;
isreadonly = ((fsstat.f_flag & ST_RDONLY) == ST_RDONLY);
block_size = fsstat.f_frsize;
#elif defined(HAVE_STATFS)
+ MONO_ENTER_GC_SAFE;
ret = statfs (utf8_path_name, &fsstat);
+ MONO_EXIT_GC_SAFE;
#if defined (MNT_RDONLY)
isreadonly = ((fsstat.f_flags & MNT_RDONLY) == MNT_RDONLY);
#elif defined (MS_RDONLY)
GetDriveTypeFromPath (const gchar *utf8_root_path_name)
{
struct statfs buf;
-
- if (statfs (utf8_root_path_name, &buf) == -1)
+ gint res;
+
+ MONO_ENTER_GC_SAFE;
+ res = statfs (utf8_root_path_name, &buf);
+ MONO_EXIT_GC_SAFE;
+ if (res == -1)
return DRIVE_UNKNOWN;
#if PLATFORM_MACOSX
return _wapi_get_drive_type (buf.f_fstypename);
gchar buffer [512];
gchar **splitted;
+ MONO_ENTER_GC_SAFE;
fp = fopen ("/etc/mtab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL) {
+ MONO_ENTER_GC_SAFE;
fp = fopen ("/etc/mnttab", "rt");
+ MONO_EXIT_GC_SAFE;
if (fp == NULL)
return(DRIVE_UNKNOWN);
}
drive_type = DRIVE_NO_ROOT_DIR;
- while (fgets (buffer, 512, fp) != NULL) {
+ while (1) {
+ gchar *fgets_res;
+ MONO_ENTER_GC_SAFE;
+ fgets_res = fgets (buffer, 512, fp);
+ MONO_EXIT_GC_SAFE;
+ if (fgets_res == NULL)
+ break;
splitted = g_strsplit (buffer, " ", 0);
if (!*splitted || !*(splitted + 1) || !*(splitted + 2)) {
g_strfreev (splitted);
g_strfreev (splitted);
}
+ MONO_ENTER_GC_SAFE;
fclose (fp);
+ MONO_EXIT_GC_SAFE;
return drive_type;
}
#endif
return (drive_type);
}
-#if defined (PLATFORM_MACOSX) || defined (__linux__) || defined(PLATFORM_BSD) || defined(__native_client__) || defined(__FreeBSD_kernel__)
+#if defined (PLATFORM_MACOSX) || defined (__linux__) || defined(PLATFORM_BSD) || defined(__FreeBSD_kernel__) || defined(__HAIKU__)
static gchar*
get_fstypename (gchar *utfpath)
{
#if __linux__
_wapi_drive_type *current;
#endif
- if (statfs (utfpath, &stat) == -1)
+ gint statfs_res;
+ MONO_ENTER_GC_SAFE;
+ statfs_res = statfs (utfpath, &stat);
+ MONO_EXIT_GC_SAFE;
+ if (statfs_res == -1)
return NULL;
#if PLATFORM_MACOSX
return g_strdup (stat.f_fstypename);
if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE, (gpointer *)&file_handle)) {
g_warning ("%s: error looking up file handle %p", __func__, handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ 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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return FALSE;
}
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locking handle %p, offset %lld, length %lld", __func__, handle, offset, length);
#else
if (offset_high > 0 || length_high > 0) {
- SetLastError (ERROR_INVALID_PARAMETER);
+ mono_w32error_set_last (ERROR_INVALID_PARAMETER);
return FALSE;
}
offset = offset_low;
if (!mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE, (gpointer *)&file_handle)) {
g_warning ("%s: error looking up file handle %p", __func__, handle);
- SetLastError (ERROR_INVALID_HANDLE);
+ 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);
- SetLastError (ERROR_ACCESS_DENIED);
+ mono_w32error_set_last (ERROR_ACCESS_DENIED);
return FALSE;
}
void
mono_w32file_init (void)
{
- mono_os_mutex_init (&stdhandle_mutex);
- mono_os_mutex_init (&file_share_mutex);
+ mono_coop_mutex_init (&stdhandle_mutex);
+ mono_coop_mutex_init (&file_share_mutex);
mono_w32handle_register_ops (MONO_W32HANDLE_FILE, &_wapi_file_ops);
mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
/* mono_w32handle_register_capabilities (MONO_W32HANDLE_CONSOLE, */
/* MONO_W32HANDLE_CAP_WAIT); */
- if (g_getenv ("MONO_STRICT_IO_EMULATION"))
+ if (g_hasenv ("MONO_STRICT_IO_EMULATION"))
lock_while_writing = TRUE;
}
void
mono_w32file_cleanup (void)
{
- mono_os_mutex_destroy (&file_share_mutex);
+ mono_coop_mutex_destroy (&file_share_mutex);
if (file_share_table)
g_hash_table_destroy (file_share_table);
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = MoveFile (path, dest);
if (!result)
- *error = GetLastError ();
-
- MONO_EXIT_GC_SAFE;
-
+ *error = mono_w32error_get_last ();
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = CopyFile (path, dest, !overwrite);
if (!result)
- *error = GetLastError ();
-
- MONO_EXIT_GC_SAFE;
+ *error = mono_w32error_get_last ();
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
if (!result)
- *error = GetLastError ();
-
- MONO_EXIT_GC_SAFE;
-
+ *error = mono_w32error_get_last ();
return result;
}
gint64 length;
guint32 length_hi;
- MONO_ENTER_GC_SAFE;
-
length = GetFileSize (handle, &length_hi);
if(length==INVALID_FILE_SIZE) {
- *error=GetLastError ();
+ *error=mono_w32error_get_last ();
}
- MONO_EXIT_GC_SAFE;
-
return length | ((gint64)length_hi << 32);
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = LockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
if (!result)
- *error = GetLastError ();
-
- MONO_EXIT_GC_SAFE;
-
+ *error = mono_w32error_get_last ();
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
if (!result)
- *error = GetLastError ();
-
- MONO_EXIT_GC_SAFE;
-
+ *error = mono_w32error_get_last ();
return result;
}
gpointer
mono_w32file_get_console_input (void)
{
- gpointer handle;
-
- MONO_ENTER_GC_SAFE;
- handle = mono_w32file_get_std_handle (STD_INPUT_HANDLE);
- MONO_EXIT_GC_SAFE;
-
- return handle;
+ return mono_w32file_get_std_handle (STD_INPUT_HANDLE);
}
gpointer
mono_w32file_get_console_output (void)
{
- gpointer handle;
-
- MONO_ENTER_GC_SAFE;
- handle = mono_w32file_get_std_handle (STD_OUTPUT_HANDLE);
- MONO_EXIT_GC_SAFE;
-
- return handle;
+ return mono_w32file_get_std_handle (STD_OUTPUT_HANDLE);
}
gpointer
mono_w32file_get_console_error (void)
{
- gpointer handle;
-
- MONO_ENTER_GC_SAFE;
- handle = mono_w32file_get_std_handle (STD_ERROR_HANDLE);
- MONO_EXIT_GC_SAFE;
-
- return handle;
+ return mono_w32file_get_std_handle (STD_ERROR_HANDLE);
}