+/**
+ * \file
+ */
#include <config.h>
#include <glib.h>
* 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;
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;
}
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_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)
}
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));
* 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));
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));
#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 handle %p by %" G_GINT64_FORMAT " bytes from %d", __func__,
+ handle, offset, whence);
#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",
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__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: move of handle %p returning %" G_GUINT32_FORMAT "/%" G_GINT32_FORMAT, __func__,
handle, ret, highmovedistance==NULL?0:*highmovedistance);
return(ret);
* 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);
}
*/
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));
*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);
}
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));
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) {
/* 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));
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)
}
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) {
}
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)
return(FALSE);
}
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: reading up to %d bytes from pipe %p", __func__,
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: reading up to %" G_GUINT32_FORMAT " bytes from pipe %p", __func__,
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) {
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 %p", __func__,
+ numbytes, 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));
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);
((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);
((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);
*/
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);
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);
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);
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) {
mono_w32error_set_last (ERROR_SHARING_VIOLATION);
g_free (filename);
+ MONO_ENTER_GC_SAFE;
close (fd);
+ MONO_EXIT_GC_SAFE;
return (INVALID_HANDLE_VALUE);
}
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);
+ 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;
mono_w32error_set_last (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
gboolean
mono_w32file_close (gpointer handle)
{
- return mono_w32handle_close (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;
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;
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__);
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;
mono_w32error_set_last (ERROR_SHARING_VIOLATION);
return (FALSE);
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));
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);
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 = 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);
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);
}
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);
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;
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));
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]);
+ 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_w32handle_unref (read_handle);
+
+ MONO_ENTER_GC_SAFE;
+ mono_w32handle_close (read_handle);
close (filedes[0]);
close (filedes[1]);
+ MONO_EXIT_GC_SAFE;
mono_w32error_set_last (ERROR_GEN_FAILURE);
return(FALSE);
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
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)
{ DRIVE_RAMDISK, "fdesc" },
{ DRIVE_REMOTE, "ftp" },
{ DRIVE_FIXED, "hfs" },
+ { DRIVE_FIXED, "apfs" },
{ DRIVE_FIXED, "msdos" },
{ DRIVE_REMOTE, "nfs" },
{ DRIVE_FIXED, "ntfs" },
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);
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 handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
+ handle, (gint64) offset, (gint64) length);
#else
if (offset_high > 0 || length_high > 0) {
mono_w32error_set_last (ERROR_INVALID_PARAMETER);
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 handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
+ handle, (gint64) offset, (gint64) length);
#endif
return _wapi_lock_file_region (GPOINTER_TO_UINT(handle), offset, length);
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 handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__,
+ handle, (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 handle %p, offset %" G_GINT64_FORMAT ", length %" G_GINT64_FORMAT, __func__, handle, (gint64) offset, (gint64) length);
#endif
return _wapi_unlock_file_region (GPOINTER_TO_UINT(handle), offset, length);
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 = mono_w32error_get_last ();
-
- MONO_EXIT_GC_SAFE;
-
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = CopyFile (path, dest, !overwrite);
if (!result)
*error = mono_w32error_get_last ();
- MONO_EXIT_GC_SAFE;
-
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
if (!result)
*error = mono_w32error_get_last ();
-
- MONO_EXIT_GC_SAFE;
-
return result;
}
gint64 length;
guint32 length_hi;
- MONO_ENTER_GC_SAFE;
-
length = GetFileSize (handle, &length_hi);
if(length==INVALID_FILE_SIZE) {
*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 = mono_w32error_get_last ();
-
- MONO_EXIT_GC_SAFE;
-
return result;
}
{
gboolean result;
- MONO_ENTER_GC_SAFE;
-
result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
if (!result)
*error = mono_w32error_get_last ();
-
- MONO_EXIT_GC_SAFE;
-
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);
}