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

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--configure.in80
-rw-r--r--mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog4
-rw-r--r--mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs6
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/ChangeLog3
-rw-r--r--mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs5
-rwxr-xr-xmcs/class/System.Data/System.Data.SqlClient/ChangeLog4
-rw-r--r--mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs4
-rw-r--r--mcs/class/System.Data/Test/System.Data.Odbc/ChangeLog5
-rw-r--r--mcs/class/System.Data/Test/System.Data.Odbc/OdbcCommandTest.cs70
-rw-r--r--mcs/class/System.Drawing/System.Drawing/ChangeLog4
-rw-r--r--mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs6
-rw-r--r--mcs/class/System.Web/System.Web.Handlers/ChangeLog4
-rw-r--r--mcs/class/System.Web/System.Web.Handlers/TraceHandler.cs19
-rw-r--r--mcs/class/System.Web/System.Web.UI/ChangeLog7
-rwxr-xr-xmcs/class/System.Web/System.Web.UI/Page.cs11
-rw-r--r--mcs/class/System.Web/System.Web.UI/PageParser.cs14
-rw-r--r--mcs/class/System.Web/System.Web/ChangeLog5
-rw-r--r--mcs/class/System.Web/System.Web/TraceContext.cs9
-rw-r--r--mcs/class/corlib/System.Globalization/ChangeLog5
-rw-r--r--mcs/class/corlib/System.Globalization/NumberFormatInfo.cs5
-rw-r--r--mcs/class/corlib/System.Reflection/ChangeLog4
-rw-r--r--mcs/class/corlib/System.Reflection/Module.cs21
-rw-r--r--mcs/class/corlib/System.Reflection/common.src25
-rwxr-xr-xmcs/class/corlib/System.Runtime.Remoting/ChangeLog7
-rw-r--r--mcs/class/corlib/System.Runtime.Remoting/RemotingConfiguration.cs4
-rw-r--r--mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs4
-rw-r--r--mcs/class/corlib/System.Runtime.Remoting/ServerIdentity.cs8
-rw-r--r--mcs/class/corlib/Test/System.Reflection/ChangeLog4
-rw-r--r--mcs/errors/cs0502.cs11
-rw-r--r--mono/dis/get.c1
-rw-r--r--mono/io-layer/ChangeLog96
-rw-r--r--mono/io-layer/daemon.c62
-rw-r--r--mono/io-layer/error.c8
-rw-r--r--mono/io-layer/handles-private.h52
-rw-r--r--mono/io-layer/handles.c166
-rw-r--r--mono/io-layer/io.c422
-rw-r--r--mono/io-layer/mutexes.c20
-rw-r--r--mono/io-layer/sockets.c347
-rw-r--r--mono/io-layer/threads.c12
-rw-r--r--mono/io-layer/timed-thread.c2
-rw-r--r--mono/io-layer/wait.c12
-rw-r--r--mono/io-layer/wapi-private.h3
-rw-r--r--mono/metadata/ChangeLog175
-rw-r--r--mono/metadata/appdomain.c30
-rw-r--r--mono/metadata/assembly.c14
-rw-r--r--mono/metadata/class.c2
-rw-r--r--mono/metadata/debug-mono-symfile.c37
-rw-r--r--mono/metadata/filewatcher.c13
-rw-r--r--mono/metadata/gc.c72
-rw-r--r--mono/metadata/image.c21
-rw-r--r--mono/metadata/loader.c54
-rw-r--r--mono/metadata/locales.c22
-rw-r--r--mono/metadata/marshal.c25
-rw-r--r--mono/metadata/metadata.c106
-rw-r--r--mono/metadata/mono-debug.c66
-rw-r--r--mono/metadata/object.c39
-rw-r--r--mono/metadata/object.h6
-rw-r--r--mono/metadata/process.c6
-rw-r--r--mono/metadata/reflection.c46
-rw-r--r--mono/metadata/reflection.h1
-rw-r--r--mono/metadata/socket-io.c52
-rw-r--r--mono/metadata/socket-io.h15
-rw-r--r--mono/mini/ChangeLog65
-rw-r--r--mono/mini/basic-long.cs6
-rw-r--r--mono/mini/cpu-g4.md2
-rw-r--r--mono/mini/cpu-pentium.md2
-rw-r--r--mono/mini/cpu-s390.md2
-rw-r--r--mono/mini/cpu-sparc.md2
-rw-r--r--mono/mini/exceptions-x86.c6
-rw-r--r--mono/mini/inssel-long32.brg23
-rw-r--r--mono/mini/inssel-ppc.brg20
-rw-r--r--mono/mini/inssel-x86.brg2
-rw-r--r--mono/mini/inssel.brg9
-rw-r--r--mono/mini/mini-ops.h2
-rw-r--r--mono/mini/mini-ppc.c31
-rw-r--r--mono/mini/mini-s390.c4
-rw-r--r--mono/mini/mini-sparc.c3
-rw-r--r--mono/mini/mini-x86.c4
-rw-r--r--mono/mini/mini.c92
-rw-r--r--mono/mini/mini.h1
-rw-r--r--mono/tests/ChangeLog6
-rw-r--r--mono/tests/Makefile.am1
-rw-r--r--mono/tests/typeof-ptr.cs26
-rw-r--r--web/download114
-rw-r--r--web/index21
86 files changed, 2130 insertions, 699 deletions
diff --git a/ChangeLog b/ChangeLog
index 784b767dcf9..bf710d6e16c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2004-09-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * configure.in: added check for kqueue. Patch from Geoff Norton
+ in HEAD.
+
+2004-08-17 Dick Porter <dick@ximian.com>
+
+ * configure.in: Correct intl library for FreeBSD and OpenBSD.
+ Fixes bug 62884, patch by Tom McLaughlin (tmclaugh@sdf.lonestar.org).
+
+2004-07-27 John Merryweather Cooper <john_m_cooper@yahoo.com>
+ * configure.in: Disable __thread test (TLS) for FreeBSD as
+ it succeeds on FreeBSD 5.x when it should fail. Fix pthread
+ library detection for FreeBSD 4.x since pthread is embedded
+ in libc_r on this platform. Fix some typos in my host
+ regexes for freebsd.
+
+2004-07-23 Dick Porter <dick@ximian.com>
+
+ * configure.in: Changes for FreeBSD thread support by John
+ Merryweather Cooper <john_m_cooper@yahoo.com>.
+
2004-07-03 Zoltan Varga <vargaz@freemail.hu>
* configure.in: Add --with-tls option to replace the misnamed
diff --git a/configure.in b/configure.in
index 962304855f6..53475c3117d 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
AC_INIT(README)
AC_CANONICAL_SYSTEM
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(mono,1.0)
+AM_INIT_AUTOMAKE(mono,1.0.2)
AM_MAINTAINER_MODE
AC_PROG_LN_S
@@ -67,7 +67,62 @@ case "$host" in
libdl=
libgc_threads=no
;;
- *-*-*freebsd*|*-*-*openbsd*)
+# these flags will work for all versions of -STABLE
+#
+ *-*-*freebsd4*)
+ platform_win32=no
+ if test "x$PTHREAD_CFLAGS" = "x"; then
+ CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS"
+ libmono_cflags="-D_THREAD_SAFE"
+ else
+ CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS -DGC_FREEBSD_THREADS"
+ libmono_cflags="$PTHREAD_CFLAGS"
+ fi
+ if test "x$PTHREAD_LIBS" = "x"; then
+ LDFLAGS="$LDFLAGS -pthread"
+ libmono_ldflags="-pthread"
+ else
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
+ libmono_ldflags="$PTHREAD_LIBS"
+ fi
+ need_link_unlink=yes
+ AC_DEFINE(PTHREAD_POINTER_ID)
+ libdl=
+ libgc_threads=pthreads
+# TLS isn't implemented at all on -STABLE
+ with_nptl=no
+ with_tls=pthread
+ ;;
+# older versions of -CURRENT will break with these flags but testing
+# indicates these older versions won't run Mono anyway
+#
+ *-*-*freebsd5*)
+ platform_win32=no
+ if test "x$PTHREAD_CFLAGS" = "x"; then
+ CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS"
+ libmono_cflags=
+ else
+ CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS -DGC_FREEBSD_THREADS"
+ libmono_cflags="$PTHREAD_CFLAGS"
+ fi
+ if test "x$PTHREAD_LIBS" = "x"; then
+ LDFLAGS="$LDFLAGS -lpthread"
+ libmono_ldflags="-lpthread"
+ else
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
+ libmono_ldflags="$PTHREAD_LIBS"
+ fi
+ need_link_unlink=yes
+ AC_DEFINE(PTHREAD_POINTER_ID)
+ libdl=
+ libgc_threads=pthreads
+# TLS is only partially implemented on -CURRENT (compiler support
+# but NOT library support)
+#
+ with_nptl=no
+ with_tls=pthread
+ ;;
+ *-*-*openbsd*)
platform_win32=no
CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS"
libmono_cflags="-D_THREAD_SAFE"
@@ -411,6 +466,7 @@ if test x$platform_win32 = xno; then
AC_CHECK_FUNCS(getpwuid_r)
AC_CHECK_FUNCS(getresuid)
AC_CHECK_FUNCS(setresuid)
+ AC_CHECK_FUNCS(kqueue)
dnl ******************************************************************
dnl *** Check for large file support ***
@@ -653,7 +709,17 @@ if test x$platform_win32 = xno; then
dnl *****************************
dnl *** Checks for libpthread ***
dnl *****************************
- AC_CHECK_LIB(pthread, main, LIBS="$LIBS -lpthread")
+# on FreeBSD -STABLE, the pthreads functions all reside in libc_r
+# and libpthread does not exist
+#
+ case "${host}" in
+ *-*-*freebsd4*)
+ AC_CHECK_LIB(pthread, main, LIBS="$LIBS -pthread")
+ ;;
+ *)
+ AC_CHECK_LIB(pthread, main, LIBS="$LIBS -lpthread")
+ ;;
+ esac
AC_CHECK_HEADERS(pthread.h)
AC_CHECK_FUNCS(pthread_mutex_timedlock)
AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_get_np)
@@ -1201,6 +1267,14 @@ case "$host" in
LIBC="libc.so.12"
INTL="libintl.so.0"
;;
+ *-*-*freebsd*)
+ LIBC="libc.so"
+ INTL="libintl.so"
+ ;;
+ *-*-*openbsd*)
+ LIBC="libc.so"
+ INTL="libintl.so"
+ ;;
esac
AC_SUBST(libsuffix)
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
index bcf7dd8b1f8..42df9e1632a 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
@@ -1,3 +1,7 @@
+2004-06-30 Umadevi S <sumadevi@novell.com>
+ * Tds.cs - In the NextResult method handling TdsPacketSubType. TableName.
+
+
2004-04-22 Sebastien Pouliot <sebastien@ximian.com>
* Tds70.cs: Updated to match changes in Mono.Security.dll.
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
index 1a917399a3f..e1cf4697ee7 100644
--- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
+++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
@@ -293,6 +293,12 @@ namespace Mono.Data.Tds.Protocol {
break;
case TdsPacketSubType.TableName:
+ // done = true;
+ peek = Comm.Peek ();
+ done = (peek != (byte) TdsPacketSubType.ColumnDetail);
+
+ break;
+ case TdsPacketSubType.ColumnDetail:
done = true;
break;
default:
diff --git a/mcs/class/System.Data/System.Data.Odbc/ChangeLog b/mcs/class/System.Data/System.Data.Odbc/ChangeLog
index 91adfefb77e..d8581c1975b 100644
--- a/mcs/class/System.Data/System.Data.Odbc/ChangeLog
+++ b/mcs/class/System.Data/System.Data.Odbc/ChangeLog
@@ -1,6 +1,3 @@
-2004-07-01 Sureshkumar T (tsureshkumar@novell.com)
- * OdbcCommand.cs : fixed reader problem with ExecuteScalar
-
2004-06-23 Sureshkumar T (tsureshkumar@novell.com)
* OdbcConnection.cs: Fix: Moved env allocation to Open method.
Disconnection & freeing handles are done in Close
diff --git a/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs b/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
index e21349af2a9..fe242f3bf8f 100644
--- a/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
+++ b/mcs/class/System.Data/System.Data.Odbc/OdbcCommand.cs
@@ -342,12 +342,11 @@ namespace System.Data.Odbc
public object ExecuteScalar ()
{
- object val = null;
+ object val;
OdbcDataReader reader=ExecuteReader();
try
{
- if (reader.Read ())
- val=reader[0];
+ val=reader[0];
}
finally
{
diff --git a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
index 14efc7d3b1e..5576c7f7c6b 100755
--- a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
+++ b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
@@ -1,3 +1,7 @@
+2004-06-30 Umadevi S <sumadevi@novell.com>
+ * SqlCommand.cs : In the Execute Method the commandbehavior parameters were ignored correct
+these
+
2004-06-22 Atsushi Enomoto <atsushi@ximian.com>
* SqlCommandBuilder.cs : Avoid cast exception caused by DbNull.
diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
index 366b381b54d..21978c14cf2 100644
--- a/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
+++ b/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
@@ -268,8 +268,8 @@ namespace System.Data.SqlClient {
{
TdsMetaParameterCollection parms = Parameters.MetaParameters;
if (preparedStatement == null) {
- bool schemaOnly = ((CommandBehavior & CommandBehavior.SchemaOnly) > 0);
- bool keyInfo = ((CommandBehavior & CommandBehavior.KeyInfo) > 0);
+ bool schemaOnly = ((behavior & CommandBehavior.SchemaOnly) > 0);
+ bool keyInfo = ((behavior & CommandBehavior.KeyInfo) > 0);
StringBuilder sql1 = new StringBuilder ();
StringBuilder sql2 = new StringBuilder ();
diff --git a/mcs/class/System.Data/Test/System.Data.Odbc/ChangeLog b/mcs/class/System.Data/Test/System.Data.Odbc/ChangeLog
index 8df7a0151f2..bd7b77d4f19 100644
--- a/mcs/class/System.Data/Test/System.Data.Odbc/ChangeLog
+++ b/mcs/class/System.Data/Test/System.Data.Odbc/ChangeLog
@@ -1,8 +1,3 @@
-2004-07-01 Sureshkumar T <tsureshkumar@novell.com>
- * Added test case for OdbcCommand.ExecuteScalar Method
- * New files:
- OdbcCommandTest.cs - test suite for OdbcCommand class.
-
2004-06-23 Sureshkumar T <TSureshkumar@novell.com>
* Added test to check whether the OdbcConnection.Close method closes
all the handles.
diff --git a/mcs/class/System.Data/Test/System.Data.Odbc/OdbcCommandTest.cs b/mcs/class/System.Data/Test/System.Data.Odbc/OdbcCommandTest.cs
deleted file mode 100644
index 8b3968c7062..00000000000
--- a/mcs/class/System.Data/Test/System.Data.Odbc/OdbcCommandTest.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// OdbcCommandTest.cs - NUnit Test Cases for testing the
-// OdbcCommand class
-//
-// Author:
-// Sureshkumar T (TSureshkumar@novell.com)
-//
-// Copyright (c) 2004 Novell Inc., and the individuals listed
-// on the ChangeLog entries.
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-
-using System;
-using System.Data;
-using System.Data.Odbc;
-
-using NUnit.Framework;
-
-namespace MonoTests.System.Data.Odbc
-{
-
- [TestFixture]
- public class OdbcCommandTest : MySqlOdbcBaseClient
- {
-
- [SetUp]
- public void GetReady () {
- OpenConnection ();
- CreateTestSetup (); // create database & test tables
- }
-
- [TearDown]
- public void Clean () {
- CleanTestSetup (); // clean test database;
- CloseConnection ();
- }
-
- /// <summary>
- /// Test Execute Scalar Method
- /// </summary>
- [Test]
- public void ExecuteScalarTest ()
- {
- OdbcCommand cmd = conn.CreateCommand ();
- string query = "select count(*) from test order by col_int;";
- cmd.CommandText = query;
- object objCount = cmd.ExecuteScalar ();
- Assertion.AssertEquals( "ExecuteScalar does not return int type", 5, Convert.ToInt32(objCount));
- }
- }
-}
diff --git a/mcs/class/System.Drawing/System.Drawing/ChangeLog b/mcs/class/System.Drawing/System.Drawing/ChangeLog
index ee4e72e3e57..941f5db4a6c 100644
--- a/mcs/class/System.Drawing/System.Drawing/ChangeLog
+++ b/mcs/class/System.Drawing/System.Drawing/ChangeLog
@@ -1,7 +1,3 @@
-2004-07-02 Jordi Mas i Hernandez <jordi@ximian.com>
-
- * gdipFunctions.cs: fixes bug 61050
-
2004-06-24 Sanjay Gupta <gsanjay@novell.com>
* ImageAnimator.cs: Rewrote complete implementation.
diff --git a/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs b/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
index 5244cd50235..8db7223a85c 100644
--- a/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
+++ b/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
@@ -1418,11 +1418,7 @@ namespace System.Drawing
{
public Stream stream;
- public GdiPlusStreamHelper (Stream s)
- {
- stream = s;
- stream.Seek(0, SeekOrigin.Begin);
- }
+ public GdiPlusStreamHelper (Stream s) { stream = s; }
public int StreamGetBytesImpl (IntPtr buf, int bufsz, bool peek)
{
diff --git a/mcs/class/System.Web/System.Web.Handlers/ChangeLog b/mcs/class/System.Web/System.Web.Handlers/ChangeLog
index 50459bd9024..ebddbc1e4ba 100644
--- a/mcs/class/System.Web/System.Web.Handlers/ChangeLog
+++ b/mcs/class/System.Web/System.Web.Handlers/ChangeLog
@@ -1,7 +1,3 @@
-2004-07-02 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * TraceHandler.cs: check that trace is enabled or throw.
-
2004-06-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* TraceHandler.cs: Added protected missing members and attributes.
diff --git a/mcs/class/System.Web/System.Web.Handlers/TraceHandler.cs b/mcs/class/System.Web/System.Web.Handlers/TraceHandler.cs
index 343aa5957a7..33385dbf5fb 100644
--- a/mcs/class/System.Web/System.Web.Handlers/TraceHandler.cs
+++ b/mcs/class/System.Web/System.Web.Handlers/TraceHandler.cs
@@ -39,27 +39,16 @@ using System.Web.UI.WebControls;
namespace System.Web.Handlers
{
-#if NET_2_0
- [Serializable]
-#endif
- class TraceNotAvailableException : HttpException
- {
- public TraceNotAvailableException () :
- base ("Trace Error") {}
-
- internal override string Description {
- get { return "Trace.axd is not enabled in the configuration file for this application."; }
- }
- }
-
public class TraceHandler : IHttpHandler
{
void IHttpHandler.ProcessRequest (HttpContext context)
{
TraceManager manager = HttpRuntime.TraceManager;
- if (!manager.Enabled || manager.LocalOnly && !context.Request.IsLocal) {
- throw new TraceNotAvailableException ();
+ if (manager.LocalOnly && !context.Request.IsLocal) {
+ // Need to figure out the error message that goes here
+ // but I only have cassini for testing
+ return;
}
HtmlTextWriter output = new HtmlTextWriter (context.Response.Output);
diff --git a/mcs/class/System.Web/System.Web.UI/ChangeLog b/mcs/class/System.Web/System.Web.UI/ChangeLog
index ec02b96092f..07d62fd2c33 100644
--- a/mcs/class/System.Web/System.Web.UI/ChangeLog
+++ b/mcs/class/System.Web/System.Web.UI/ChangeLog
@@ -1,10 +1,3 @@
-2004-07-02 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * Page.cs: added additional checks for saving/displaying trace data.
-
- * PageParser.cs: removed checks for trace enabled in configuration
- files.
-
2004-06-29 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* ControlCollection.cs: when clearing the control collection, tell the
diff --git a/mcs/class/System.Web/System.Web.UI/Page.cs b/mcs/class/System.Web/System.Web.UI/Page.cs
index 79a68d2e233..3887c9c35e0 100755
--- a/mcs/class/System.Web/System.Web.UI/Page.cs
+++ b/mcs/class/System.Web/System.Web.UI/Page.cs
@@ -769,18 +769,11 @@ public class Page : TemplateControl, IHttpHandler
private void RenderTrace (HtmlTextWriter output)
{
- TraceManager traceManager = HttpRuntime.TraceManager;
-
- if (Trace.HaveTrace && !Trace.IsEnabled || !Trace.HaveTrace && !traceManager.Enabled)
+ if (!Trace.IsEnabled)
return;
Trace.SaveData ();
-
- if (!Trace.HaveTrace && traceManager.Enabled && !traceManager.PageOutput)
- return;
-
- if (!traceManager.LocalOnly || Context.Request.IsLocal)
- Trace.Render (output);
+ Trace.Render (output);
}
internal void RaisePostBackEvents ()
diff --git a/mcs/class/System.Web/System.Web.UI/PageParser.cs b/mcs/class/System.Web/System.Web.UI/PageParser.cs
index 571edf2997a..816d83c0bc8 100644
--- a/mcs/class/System.Web/System.Web.UI/PageParser.cs
+++ b/mcs/class/System.Web/System.Web.UI/PageParser.cs
@@ -199,6 +199,13 @@ namespace System.Web.UI
}
}
+ TraceConfig traceConfig = (TraceConfig) Context.GetConfig ("system.web/trace");
+ if (traceConfig != null) {
+ trace = traceConfig.Enabled;
+ if (trace)
+ haveTrace = true;
+ }
+
string tracestr = GetString (atts, "Trace", null);
if (tracestr != null) {
haveTrace = true;
@@ -220,6 +227,13 @@ namespace System.Web.UI
"one of the following values: SortByTime, SortByCategory.");
}
+ if (traceConfig != null) {
+ if (traceConfig.LocalOnly && !Context.Request.IsLocal) {
+ haveTrace = false;
+ trace = false;
+ }
+ }
+
errorPage = GetString (atts, "ErrorPage", null);
validateRequest = GetBool (atts, "ValidateRequest", PagesConfig.ValidateRequest);
clientTarget = GetString (atts, "ClientTarget", null);
diff --git a/mcs/class/System.Web/System.Web/ChangeLog b/mcs/class/System.Web/System.Web/ChangeLog
index 7be6f4e6a5f..93cc846bb86 100644
--- a/mcs/class/System.Web/System.Web/ChangeLog
+++ b/mcs/class/System.Web/System.Web/ChangeLog
@@ -1,8 +1,3 @@
-2004-07-02 Gonzalo Paniagua Javier <gonzalo@ximian.com>
-
- * TraceContext.cs: added internal HaveTrace property whose
- value is true when the page has a Trace attribute.
-
2004-06-15 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* TraceData.cs: fixed <br> output. Closes bug #60181.
diff --git a/mcs/class/System.Web/System.Web/TraceContext.cs b/mcs/class/System.Web/System.Web/TraceContext.cs
index f939add498b..6d7a7c68608 100644
--- a/mcs/class/System.Web/System.Web/TraceContext.cs
+++ b/mcs/class/System.Web/System.Web/TraceContext.cs
@@ -42,19 +42,11 @@ namespace System.Web {
private TraceMode _Mode;
private TraceData data;
private bool data_saved;
- private bool _haveTrace = false;
public TraceContext(HttpContext Context) {
_Context = Context;
_Enabled = false;
}
-
-
- internal bool HaveTrace {
- get {
- return _haveTrace;
- }
- }
public bool IsEnabled {
get {
@@ -64,7 +56,6 @@ namespace System.Web {
set {
if (value && data == null)
data = new TraceData ();
- _haveTrace = true;
_Enabled = value;
}
}
diff --git a/mcs/class/corlib/System.Globalization/ChangeLog b/mcs/class/corlib/System.Globalization/ChangeLog
index 95392d51e96..533cc9d4dc7 100644
--- a/mcs/class/corlib/System.Globalization/ChangeLog
+++ b/mcs/class/corlib/System.Globalization/ChangeLog
@@ -1,3 +1,8 @@
+
+Wed Jun 30 17:06:43 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * NumberFormatInfo.cs: workaround for bug 55978.
+
2004-06-17 Atsushi Enomoto <atsushi@ximian.com>
* DateTimeFormatInfo.cs : check if pattern array is empty or not. Now
diff --git a/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs b/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs
index 169ad6c2f9e..e884daad5a7 100644
--- a/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs
+++ b/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs
@@ -851,7 +851,10 @@ throw new Exception ("HERE the value was modified");
public object GetFormat (Type formatType)
{
- return (formatType == typeof (NumberFormatInfo)) ? this : null;
+ // work around http://bugzilla.ximian.com/show_bug.cgi?id=55978
+ // the comparison fails because formatType likely comes from another domain
+ //return (formatType == typeof (NumberFormatInfo)) ? this : null;
+ return this;
}
public object Clone ()
diff --git a/mcs/class/corlib/System.Reflection/ChangeLog b/mcs/class/corlib/System.Reflection/ChangeLog
index d2fd0f4ac62..8a7945e688e 100644
--- a/mcs/class/corlib/System.Reflection/ChangeLog
+++ b/mcs/class/corlib/System.Reflection/ChangeLog
@@ -1,7 +1,3 @@
-2004-07-03 Zoltan Varga <vargaz@freemail.hu>
-
- * Module.cs: Initialize FilterTypeName[IgnoreCase]. Fixes #61048.
-
2004-06-17 Gert Driesen <drieseng@users.sourceforge.net>
* Pointer.cs: remove serializable attribute to match MS.NET
diff --git a/mcs/class/corlib/System.Reflection/Module.cs b/mcs/class/corlib/System.Reflection/Module.cs
index d45802fa3b3..01dc55f9be6 100644
--- a/mcs/class/corlib/System.Reflection/Module.cs
+++ b/mcs/class/corlib/System.Reflection/Module.cs
@@ -55,11 +55,6 @@ namespace System.Reflection {
const BindingFlags defaultBindingFlags =
BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
- static Module () {
- FilterTypeName = new TypeFilter (filter_by_type_name);
- FilterTypeNameIgnoreCase = new TypeFilter (filter_by_type_name_ignore_case);
- }
-
internal Module () { }
~Module () {
@@ -220,22 +215,6 @@ namespace System.Reflection {
return new Guid (GetGuidInternal ());
}
- private static bool filter_by_type_name (Type m, object filterCriteria) {
- string s = (string)filterCriteria;
- if (s.EndsWith ("*"))
- return m.Name.StartsWith (s.Substring (0, s.Length - 1));
- else
- return m.Name == s;
- }
-
- private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
- string s = (string)filterCriteria;
- if (s.EndsWith ("*"))
- return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
- else
- return String.Compare (m.Name, s, true) == 0;
- }
-
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern string GetGuidInternal ();
diff --git a/mcs/class/corlib/System.Reflection/common.src b/mcs/class/corlib/System.Reflection/common.src
new file mode 100644
index 00000000000..022b6768fcc
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/common.src
@@ -0,0 +1,25 @@
+Assembly.cs
+AssemblyNameFlags.cs
+BindingFlags.cs
+CallingConventions.cs
+ConstructorInfo.cs
+DefaultMemberAttribute.cs
+EventAttributes.cs
+EventInfo.cs
+FieldAttributes.cs
+FieldInfo.cs
+ICustomAttributeProvider.cs
+MemberFilter.cs
+MemberInfo.cs
+MemberTypes.cs
+MethodAttributes.cs
+MethodBase.cs
+MethodImplAttributes.cs
+MethodInfo.cs
+Module.cs
+ParameterAttributes.cs
+PropertyAttributes.cs
+PropertyInfo.cs
+ResourceAttributes.cs
+ResourceLocation.cs
+TypeAttributes.cs
diff --git a/mcs/class/corlib/System.Runtime.Remoting/ChangeLog b/mcs/class/corlib/System.Runtime.Remoting/ChangeLog
index de3e2e619b5..1fc62be042d 100755
--- a/mcs/class/corlib/System.Runtime.Remoting/ChangeLog
+++ b/mcs/class/corlib/System.Runtime.Remoting/ChangeLog
@@ -1,10 +1,3 @@
-2004-07-02 Lluis Sanchez Gual <lluis@ximian.com>
-
- * RemotingConfiguration.cs: Avoid adding "id" and "type" as custom
- properties of providers. This fixes bug #60934.
- * ServerIdentity.cs, RemotingServices.cs: When disposing an identity, detach
- the identity from the object, so it can be safely marshalled again.
-
2004-06-15 Gert Driesen <drieseng@users.sourceforge.net>
* RemotingTimeoutException.cs: added missing serialization ctor
diff --git a/mcs/class/corlib/System.Runtime.Remoting/RemotingConfiguration.cs b/mcs/class/corlib/System.Runtime.Remoting/RemotingConfiguration.cs
index 2cbe62dff51..204bc6b4368 100644
--- a/mcs/class/corlib/System.Runtime.Remoting/RemotingConfiguration.cs
+++ b/mcs/class/corlib/System.Runtime.Remoting/RemotingConfiguration.cs
@@ -721,9 +721,9 @@ namespace System.Runtime.Remoting
if (at == "id" && isTemplate)
prov.Id = val;
- else if (at == "type")
+ if (at == "type")
prov.Type = val;
- else if (at == "ref" && !isTemplate)
+ if (at == "ref" && !isTemplate)
prov.Ref = val;
else
prov.CustomProperties.Add (at, val);
diff --git a/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs b/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
index 475164d981a..aa694cbb3b6 100644
--- a/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
+++ b/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
@@ -159,10 +159,8 @@ namespace System.Runtime.Remoting
else
throw new ArgumentException ("The obj parameter is a proxy.");
}
- else {
+ else
identity = obj.ObjectIdentity;
- obj.ObjectIdentity = null;
- }
if (identity == null || !identity.IsConnected)
return false;
diff --git a/mcs/class/corlib/System.Runtime.Remoting/ServerIdentity.cs b/mcs/class/corlib/System.Runtime.Remoting/ServerIdentity.cs
index 72c025121d0..f5ed96a066b 100644
--- a/mcs/class/corlib/System.Runtime.Remoting/ServerIdentity.cs
+++ b/mcs/class/corlib/System.Runtime.Remoting/ServerIdentity.cs
@@ -136,13 +136,7 @@ namespace System.Runtime.Remoting
protected void DisposeServerObject()
{
- // Detach identity from server object to avoid problems if the
- // object is marshalled again.
-
- if (_serverObject != null) {
- _serverObject.ObjectIdentity = null;
- _serverObject = null;
- }
+ _serverObject = null;
}
}
diff --git a/mcs/class/corlib/Test/System.Reflection/ChangeLog b/mcs/class/corlib/Test/System.Reflection/ChangeLog
index fd367c75537..2c5110a6ee3 100644
--- a/mcs/class/corlib/Test/System.Reflection/ChangeLog
+++ b/mcs/class/corlib/Test/System.Reflection/ChangeLog
@@ -1,7 +1,3 @@
-2004-07-03 Zoltan Varga <vargaz@freemail.hu>
-
- * ModuleTest.cs: New tests for FindTypes.
-
2004-06-10 Lluis Sanchez <lluis@ximian.com>
* AssemblyNameTest.cs: AssertEqualsByteArrays(): don't crash if arrays are
diff --git a/mcs/errors/cs0502.cs b/mcs/errors/cs0502.cs
index e2232ec0c29..b589cba2f75 100644
--- a/mcs/errors/cs0502.cs
+++ b/mcs/errors/cs0502.cs
@@ -1,6 +1,5 @@
-// cs0502.cs: The class 'Sample' is abstract and sealed
-// Line: 4
-
-abstract sealed class Sample {
-}
-
+// cs0502.cs: 'Sample' cannot be both abstract and sealed
+// Line: 4
+
+abstract sealed class Sample {
+}
diff --git a/mono/dis/get.c b/mono/dis/get.c
index 43845cd6c19..22dea4fa32a 100644
--- a/mono/dis/get.c
+++ b/mono/dis/get.c
@@ -197,6 +197,7 @@ get_typespec (MonoImage *m, guint32 idx)
if (s)
g_string_append (res, s);
}
+ g_string_append (res, "*");
break;
case MONO_TYPE_FNPTR:
diff --git a/mono/io-layer/ChangeLog b/mono/io-layer/ChangeLog
index 5b19c8ceadf..884514fe184 100644
--- a/mono/io-layer/ChangeLog
+++ b/mono/io-layer/ChangeLog
@@ -1,3 +1,99 @@
+2004-09-09 Dick Porter <dick@ximian.com>
+
+ * error.c:
+ * io.c: Set error codes everywhere.
+
+2004-09-06 Dick Porter <dick@ximian.com>
+
+ * handles.c (_wapi_handle_unref): Reset the private record's type
+ (_wapi_handle_process_fork): Fix long-standing bug in checking
+ handle return values. Also do the required bookkeeping with the
+ new process's handles.
+
+ * daemon.c: When creating a new process's handles, check whether
+ the shared space needs to be increased
+
+2004-08-19 Dick Porter <dick@ximian.com>
+
+ * handles.c (_wapi_handle_count_signalled_handles): Fix thinko
+ introduced with the fd offset stuff: unlock handles properly when
+ backing off. Fixes the monologue hang at exit.
+
+2004-08-18 Dick Porter <dick@ximian.com>
+
+ * sockets.c:
+ * io.c: Check that new fds fit in the table, return error if not
+
+ * daemon.c (_wapi_daemon_main):
+ * handles.c (shared_init): Have all processes agree on a size for
+ the fd table.
+
+2004-08-17 Dick Porter <dick@ximian.com>
+
+ * daemon.c (process_new):
+ * handles.c (_wapi_handle_new_internal): Cope when the space
+ reserved for file descriptors is larger than the shared segment
+ size. Fixes the crash reported when running mono under gdb on
+ macosx.
+
+2004-08-16 Dick Porter <dick@ximian.com>
+
+ * sockets.c:
+ * io.c:
+ * handles-private.h (_wapi_handle_fd_offset_to_handle): Improve
+ error checking with passed-in file descriptors.
+
+2004-08-11 Dick Porter <dick@ximian.com>
+
+ * sockets.c:
+ * io.c: Returned handle values are the file descriptor the handle
+ encapsulates
+
+ * handles.c:
+ * handles-private.h:
+ * daemon.c: Reserve the range of handles that can have the same
+ values as file descriptors. These won't be used, but the values
+ will be used as file, console, pipe or socket handles. The fd to
+ handle mapping is done internally and is invisible to users.
+ Fixes bug 61828.
+
+ * wapi-private.h (_WAPI_HANDLE_VERSION): Increment, because we now
+ reserve a chunk of handle space.
+
+2004-07-22 Dick Porter <dick@ximian.com>
+
+ * timed-thread.c:
+ * threads.c: Move the destruction of the internal thread data to
+ after the thread has been joined. Fixes bug 61418.
+
+2004-07-14 Dick Porter <dick@ximian.com>
+
+ * wait.c (test_and_own): When not waiting for all handles to
+ become signalled, only own and return the lowest. All the
+ documentation suggests that the old way was correct, but
+ experimentation shows it actually works like this. Patch by
+ Sébastien Robitaille
+ (sebastien.robitaille@croesus.com), fixes bug 61511.
+
+2004-07-08 Dick Porter <dick@ximian.com>
+
+ * io.c (file_seek): If there is a high 32bit offset part, make
+ sure the low part isn't sign-extended. Set error codes when
+ returning failure. Fixes bug 61131.
+
+2004-07-06 Dick Porter <dick@ximian.com>
+
+ * io.c (file_setfiletime): Check for underflow when converting to
+ time_t values. Set error codes when returning failure. Fixes bug
+ 60970.
+
+2004-07-05 Dick Porter <dick@ximian.com>
+
+ * mutexes.c (mutex_ops_init): Make the named mutex mutex sharable.
+
+ * daemon.c (unref_handle): Only destroy a handle if all processes
+ have released it, not just the current one. Fixes bug 60887.
+
2004-06-24 Dick Porter <dick@ximian.com>
* mutexes.c: Indicate when a named mutex was reused
diff --git a/mono/io-layer/daemon.c b/mono/io-layer/daemon.c
index 746fba49d17..e2eca91b3eb 100644
--- a/mono/io-layer/daemon.c
+++ b/mono/io-layer/daemon.c
@@ -340,16 +340,14 @@ static gboolean unref_handle (ChannelData *channel_data, guint32 handle)
channel_data->open_handles[handle]);
#endif
- if(channel_data->open_handles[handle]==0) {
- /* This client has released the handle */
- destroy=TRUE;
- }
-
- if(_wapi_shared_data[segment]->handles[idx].ref==0) {
+ if (_wapi_shared_data[segment]->handles[idx].ref == 0) {
gboolean was_file;
dev_t device = 0;
ino_t inode = 0;
+ /* This client has released the handle */
+ destroy=TRUE;
+
if (channel_data->open_handles[handle]!=0) {
g_warning (G_GNUC_PRETTY_FUNCTION ": per-process open_handles mismatch, set to %d, should be 0",
channel_data->open_handles[handle]);
@@ -832,23 +830,11 @@ static void send_reply (GIOChannel *channel, WapiHandleResponse *resp)
_wapi_daemon_response (g_io_channel_unix_get_fd (channel), resp);
}
-/*
- * process_new:
- * @channel: The client making the request
- * @channel_data: Our data for this channel
- * @type: type to init handle to
- *
- * Find a free handle and initialize it to 'type', increase refcnt and
- * send back a reply to the client.
- */
-static void process_new (GIOChannel *channel, ChannelData *channel_data,
- WapiHandleType type)
+static guint32 new_handle_with_shared_check (WapiHandleType type)
{
- guint32 handle;
- WapiHandleResponse resp={0};
-
- handle=_wapi_handle_new_internal (type);
- if(handle==0) {
+ guint32 handle = 0;
+
+ while ((handle = _wapi_handle_new_internal (type)) == 0) {
/* Try and allocate a new shared segment, and have
* another go
*/
@@ -873,15 +859,34 @@ static void process_new (GIOChannel *channel, ChannelData *channel_data,
channels[i].open_handles=_wapi_g_renew0 (channels[i].open_handles, old_len, new_len);
}
}
-
- handle=_wapi_handle_new_internal (type);
} else {
/* Map failed. Just return 0 meaning "out of
* handles"
*/
+ break;
}
}
+ return(handle);
+}
+
+/*
+ * process_new:
+ * @channel: The client making the request
+ * @channel_data: Our data for this channel
+ * @type: type to init handle to
+ *
+ * Find a free handle and initialize it to 'type', increase refcnt and
+ * send back a reply to the client.
+ */
+static void process_new (GIOChannel *channel, ChannelData *channel_data,
+ WapiHandleType type)
+{
+ guint32 handle;
+ WapiHandleResponse resp={0};
+
+ handle = new_handle_with_shared_check (type);
+
/* handle might still be set to 0. This is handled at the
* client end
*/
@@ -1066,11 +1071,11 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
* client must check if either handle is 0 and take
* appropriate error handling action.
*/
- process_handle=_wapi_handle_new_internal (WAPI_HANDLE_PROCESS);
+ process_handle = new_handle_with_shared_check (WAPI_HANDLE_PROCESS);
ref_handle (daemon_channel_data, process_handle);
ref_handle (channel_data, process_handle);
- thread_handle=_wapi_handle_new_internal (WAPI_HANDLE_THREAD);
+ thread_handle = new_handle_with_shared_check (WAPI_HANDLE_THREAD);
ref_handle (daemon_channel_data, thread_handle);
ref_handle (channel_data, thread_handle);
@@ -1248,7 +1253,7 @@ static void process_process_fork (GIOChannel *channel, ChannelData *channel_data
resp.u.process_fork.pid=pid;
}
-
+
resp.u.process_fork.process_handle=process_handle;
resp.u.process_fork.thread_handle=thread_handle;
@@ -1493,6 +1498,9 @@ void _wapi_daemon_main(gpointer data, gpointer scratch)
/* Note that we've got the starting segment already */
_wapi_shared_data[0]->num_segments=1;
_wapi_shm_mapped_segments=1;
+
+ _wapi_fd_offset_table_size=getdtablesize ();
+ _wapi_shared_data[0]->fd_offset_table_size = _wapi_fd_offset_table_size;
startup ();
diff --git a/mono/io-layer/error.c b/mono/io-layer/error.c
index ee6dd56c96e..b167c1e9999 100644
--- a/mono/io-layer/error.c
+++ b/mono/io-layer/error.c
@@ -194,6 +194,14 @@ _wapi_get_win32_file_error (gint err)
ret = ERROR_NOT_SUPPORTED;
break;
+ case EBADF:
+ ret = ERROR_INVALID_HANDLE;
+ break;
+
+ case EIO:
+ ret = ERROR_INVALID_HANDLE;
+ break;
+
default:
g_message ("Unknown errno: %s\n", strerror (err));
ret = ERROR_GEN_FAILURE;
diff --git a/mono/io-layer/handles-private.h b/mono/io-layer/handles-private.h
index 674e01384b9..36890a97160 100644
--- a/mono/io-layer/handles-private.h
+++ b/mono/io-layer/handles-private.h
@@ -28,6 +28,9 @@ extern struct _WapiHandlePrivate_list **_wapi_private_data;
extern pthread_mutex_t _wapi_shared_mutex;
extern guint32 _wapi_shm_mapped_segments;
+extern guint32 _wapi_fd_offset_table_size;
+extern gpointer *_wapi_fd_offset_table;
+
extern guint32 _wapi_handle_new_internal (WapiHandleType type);
extern gpointer _wapi_handle_new (WapiHandleType type);
extern gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
@@ -93,6 +96,43 @@ extern gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode,
extern void _wapi_handle_set_share (dev_t device, ino_t inode,
guint32 sharemode, guint32 access);
+static inline void _wapi_handle_fd_offset_store (int fd, gpointer handle)
+{
+ g_assert (fd < _wapi_fd_offset_table_size);
+ g_assert (_wapi_fd_offset_table[fd]==NULL || handle==NULL);
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size || handle==NULL);
+
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Assigning fd offset %d to %p", fd,
+ handle);
+#endif
+
+ _wapi_fd_offset_table[fd]=handle;
+}
+
+static inline gpointer _wapi_handle_fd_offset_to_handle (gpointer fd_handle)
+{
+ int fd = GPOINTER_TO_INT (fd_handle);
+ gpointer handle;
+
+ if (fd >= _wapi_fd_offset_table_size) {
+ return(NULL);
+ }
+
+ handle = _wapi_fd_offset_table[fd];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ return(NULL);
+ }
+
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": Returning fd offset %d of %p", fd,
+ handle);
+#endif
+
+ return(handle);
+}
+
static inline struct _WapiHandleShared_list *_wapi_handle_get_shared_segment (guint32 segment)
{
struct _WapiHandleShared_list *shared;
@@ -225,6 +265,10 @@ static inline WapiHandleType _wapi_handle_type (gpointer handle)
guint32 idx;
guint32 segment;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
if(segment>=_wapi_shm_mapped_segments)
@@ -242,6 +286,8 @@ static inline void _wapi_handle_set_signal_state (gpointer handle,
struct _WapiHandleShared *shared_handle;
int thr_ret;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
_wapi_handle_segment (handle, &segment, &idx);
shared_handle=&_wapi_handle_get_shared_segment (segment)->handles[idx];
@@ -317,6 +363,8 @@ static inline gboolean _wapi_handle_issignalled (gpointer handle)
guint32 idx;
guint32 segment;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
_wapi_handle_segment (handle, &segment, &idx);
return(_wapi_handle_get_shared_segment (segment)->handles[idx].signalled);
@@ -352,6 +400,8 @@ static inline int _wapi_handle_lock_handle (gpointer handle)
guint32 idx;
guint32 segment;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": locking handle %p", handle);
#endif
@@ -369,6 +419,8 @@ static inline int _wapi_handle_unlock_handle (gpointer handle)
guint32 segment;
int ret;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": unlocking handle %p", handle);
#endif
diff --git a/mono/io-layer/handles.c b/mono/io-layer/handles.c
index 769235fe76d..a1c3dde13ef 100644
--- a/mono/io-layer/handles.c
+++ b/mono/io-layer/handles.c
@@ -77,6 +77,9 @@ pthread_mutex_t _wapi_shared_mutex=PTHREAD_MUTEX_INITIALIZER;
*/
guint32 _wapi_shm_mapped_segments;
+guint32 _wapi_fd_offset_table_size;
+gpointer *_wapi_fd_offset_table=NULL;
+
static void shared_init (void)
{
struct sockaddr_un shared_socket_address;
@@ -86,7 +89,7 @@ static void shared_init (void)
_wapi_shared_data=g_new0 (struct _WapiHandleShared_list *, 1);
_wapi_private_data=g_new0 (struct _WapiHandlePrivate_list *, 1);
-
+
attach_again:
#ifndef DISABLE_SHARED_HANDLES
@@ -146,6 +149,9 @@ attach_again:
goto attach_again;
}
+ } else {
+ _wapi_fd_offset_table_size = _wapi_shared_data[0]->fd_offset_table_size;
+ _wapi_fd_offset_table=g_new0 (gpointer, _wapi_fd_offset_table_size);
}
}
@@ -158,6 +164,10 @@ attach_again:
_wapi_shared_data[0]->num_segments=1;
_wapi_shared_scratch=g_new0 (struct _WapiHandleScratch, 1);
+
+ _wapi_fd_offset_table_size=getdtablesize ();
+ _wapi_fd_offset_table=g_new0 (gpointer,
+ _wapi_fd_offset_table_size);
}
_wapi_private_data[0]=g_new0 (struct _WapiHandlePrivate_list, 1);
_wapi_shm_mapped_segments=1;
@@ -240,6 +250,7 @@ guint32 _wapi_handle_new_internal (WapiHandleType type)
guint32 i, j;
static guint32 last=1;
int thr_ret;
+ guint32 num_segments = _wapi_handle_get_shared_segment (0)->num_segments;
/* A linear scan should be fast enough. Start from the last
* allocation, assuming that handles are allocated more often
@@ -250,8 +261,7 @@ guint32 _wapi_handle_new_internal (WapiHandleType type)
#endif
again:
_wapi_handle_segment (GUINT_TO_POINTER (last), &segment, &idx);
- for(i=segment; i<_wapi_handle_get_shared_segment (0)->num_segments;
- i++) {
+ for(i=segment; i < num_segments; i++) {
if(i!=segment) {
idx=0;
}
@@ -259,8 +269,20 @@ again:
for(j=idx; j<_WAPI_HANDLES_PER_SEGMENT; j++) {
struct _WapiHandleShared *shared;
- /* Make sure we dont try and assign handle 0 */
- if (i==0 && j==0) {
+ /* Make sure we dont try and assign the
+ * handles that would clash with fds
+ */
+ if ((i * _WAPI_HANDLES_PER_SEGMENT + j) < _wapi_fd_offset_table_size) {
+ i = _wapi_fd_offset_table_size / _WAPI_HANDLES_PER_SEGMENT;
+ j = _wapi_fd_offset_table_size - (i * _WAPI_HANDLES_PER_SEGMENT);
+
+ if (i >= num_segments) {
+ /* Need to get the caller to
+ * add more shared segments
+ */
+ return(0);
+ }
+
continue;
}
@@ -314,7 +336,7 @@ gpointer _wapi_handle_new (WapiHandleType type)
int thr_ret;
mono_once (&shared_init_once, shared_init);
-
+
again:
if(shared==TRUE) {
new.type=WapiHandleRequestType_New;
@@ -336,8 +358,7 @@ again:
thr_ret = pthread_mutex_lock (&scan_mutex);
g_assert (thr_ret == 0);
- handle_idx=_wapi_handle_new_internal (type);
- if(handle_idx==0) {
+ while ((handle_idx = _wapi_handle_new_internal (type)) == 0) {
/* Try and get a new segment, and have another go */
segment=_wapi_handle_get_shared_segment (0)->num_segments;
_wapi_handle_ensure_mapped (segment);
@@ -345,7 +366,6 @@ again:
if(_wapi_handle_get_shared_segment (segment)!=NULL) {
/* Got a new segment */
_wapi_handle_get_shared_segment (0)->num_segments++;
- handle_idx=_wapi_handle_new_internal (type);
} else {
/* Map failed. Just return 0 meaning
* "out of handles"
@@ -361,6 +381,9 @@ again:
pthread_cleanup_pop (0);
}
+ /* Make sure we left the space for fd mappings */
+ g_assert (handle_idx >= _wapi_fd_offset_table_size);
+
if(handle_idx==0) {
g_warning (G_GNUC_PRETTY_FUNCTION ": Ran out of handles!");
@@ -414,6 +437,8 @@ gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
guint32 idx;
guint32 segment;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
_wapi_handle_segment (handle, &segment, &idx);
_wapi_handle_ensure_mapped (segment);
@@ -592,6 +617,8 @@ gpointer _wapi_search_handle_namespace (WapiHandleType type,
void _wapi_handle_ref (gpointer handle)
{
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
if(shared==TRUE) {
WapiHandleRequest req={0};
WapiHandleResponse resp={0};
@@ -628,6 +655,8 @@ void _wapi_handle_unref (gpointer handle)
gboolean destroy = FALSE;
int thr_ret;
+ g_assert (GPOINTER_TO_UINT (handle) >= _wapi_fd_offset_table_size);
+
_wapi_handle_segment (handle, &segment, &idx);
if(shared==TRUE) {
@@ -676,6 +705,7 @@ void _wapi_handle_unref (gpointer handle)
_wapi_handle_ops_close_private (handle);
_wapi_handle_get_shared_segment (segment)->handles[idx].type=WAPI_HANDLE_UNUSED;
+ _wapi_handle_get_private_segment (segment)->handles[idx].type=WAPI_HANDLE_UNUSED;
/* Destroy the mutex and cond var. We hope nobody
* tried to grab them between the handle unlock and
@@ -1180,6 +1210,10 @@ gboolean _wapi_handle_test_capabilities (gpointer handle,
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1197,6 +1231,10 @@ void _wapi_handle_ops_close_shared (gpointer handle)
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1211,6 +1249,10 @@ void _wapi_handle_ops_close_private (gpointer handle)
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1232,6 +1274,10 @@ void _wapi_handle_ops_signal (gpointer handle)
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1246,6 +1292,10 @@ void _wapi_handle_ops_own (gpointer handle)
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1260,6 +1310,10 @@ gboolean _wapi_handle_ops_isowned (gpointer handle)
guint32 idx, segment;
WapiHandleType type;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
type=_wapi_handle_get_shared_segment (segment)->handles[idx].type;
@@ -1284,6 +1338,14 @@ gboolean _wapi_handle_ops_isowned (gpointer handle)
*/
gboolean CloseHandle(gpointer handle)
{
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
+ if (handle == NULL) {
+ return(FALSE);
+ }
+
_wapi_handle_unref (handle);
return(TRUE);
@@ -1303,12 +1365,17 @@ gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
again:
for(i=0; i<numhandles; i++) {
guint32 idx, segment;
+ gpointer handle = handles[i];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
- _wapi_handle_segment (handles[i], &segment, &idx);
+ _wapi_handle_segment (handle, &segment, &idx);
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": attempting to lock %p",
- handles[i]);
+ handle);
#endif
ret=mono_mutex_trylock (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_mutex);
@@ -1317,11 +1384,17 @@ again:
struct timespec sleepytime;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": attempt failed for %p", handles[i]);
+ g_message (G_GNUC_PRETTY_FUNCTION ": attempt failed for %p: %s", handle, strerror (ret));
#endif
while(i--) {
- _wapi_handle_segment (handles[i], &segment, &idx);
+ handle = handles[i];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
+ _wapi_handle_segment (handle, &segment, &idx);
thr_ret = mono_mutex_unlock (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_mutex);
g_assert (thr_ret == 0);
}
@@ -1359,24 +1432,29 @@ again:
for(i=0; i<numhandles; i++) {
guint32 idx, segment;
-
- _wapi_handle_ref (handles[i]);
+ gpointer handle = handles[i];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
+ _wapi_handle_ref (handle);
- _wapi_handle_segment (handles[i], &segment, &idx);
+ _wapi_handle_segment (handle, &segment, &idx);
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": Checking handle %p",
- handles[i]);
+ handle);
#endif
- if(((_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_OWN)==TRUE) &&
- (_wapi_handle_ops_isowned (handles[i])==TRUE)) ||
+ if(((_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_OWN)==TRUE) &&
+ (_wapi_handle_ops_isowned (handle)==TRUE)) ||
(_wapi_handle_get_shared_segment (segment)->handles[idx].signalled==TRUE)) {
count++;
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION
- ": Handle %p signalled", handles[i]);
+ ": Handle %p signalled", handle);
#endif
if(*lowest>i) {
*lowest=i;
@@ -1412,18 +1490,23 @@ void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles)
for(i=0; i<numhandles; i++) {
guint32 idx, segment;
-
- _wapi_handle_segment (handles[i], &segment, &idx);
+ gpointer handle = handles[i];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
+ _wapi_handle_segment (handle, &segment, &idx);
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": unlocking handle %p",
- handles[i]);
+ handle);
#endif
thr_ret = mono_mutex_unlock (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_mutex);
g_assert (thr_ret == 0);
- _wapi_handle_unref (handles[i]);
+ _wapi_handle_unref (handle);
}
}
@@ -1495,6 +1578,10 @@ int _wapi_handle_wait_signal_handle (gpointer handle)
#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED != -1
guint32 idx, segment;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
return(mono_cond_wait (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_cond,
@@ -1504,6 +1591,10 @@ int _wapi_handle_wait_signal_handle (gpointer handle)
struct timespec fake_timeout;
int ret;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
_wapi_calc_timeout (&fake_timeout, 100);
@@ -1524,6 +1615,10 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED != -1
guint32 idx, segment;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
return(mono_cond_timedwait (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_cond,
@@ -1534,6 +1629,10 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
struct timespec fake_timeout;
int ret;
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
_wapi_calc_timeout (&fake_timeout, 100);
@@ -1609,9 +1708,26 @@ gboolean _wapi_handle_process_fork (guint32 cmd, guint32 env, guint32 dir,
* exec_errno will be set, and the handle will be
* signalled immediately.
*/
- if(process_handle==0 || thread_handle==0) {
+ if(*process_handle==0 || *thread_handle==0) {
return(FALSE);
} else {
+ /* This call returns new handles, so we need to do
+ * a little bookkeeping
+ */
+ if (_wapi_private_data != NULL) {
+ guint32 segment, idx;
+
+ _wapi_handle_segment (*process_handle,
+ &segment, &idx);
+ _wapi_handle_ensure_mapped (segment);
+ _wapi_handle_get_private_segment (segment)->handles[idx].type = WAPI_HANDLE_PROCESS;
+
+ _wapi_handle_segment (*thread_handle,
+ &segment, &idx);
+ _wapi_handle_ensure_mapped (segment);
+ _wapi_handle_get_private_segment (segment)->handles[idx].type = WAPI_HANDLE_THREAD;
+ }
+
return(TRUE);
}
} else {
diff --git a/mono/io-layer/io.c b/mono/io-layer/io.c
index e0436186ee0..6a326e51763 100644
--- a/mono/io-layer/io.c
+++ b/mono/io-layer/io.c
@@ -236,6 +236,7 @@ static void file_close_shared (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -263,6 +264,7 @@ static void file_close_private (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -271,6 +273,9 @@ static void file_close_private (gpointer handle)
handle, file_private_handle->fd);
#endif
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (file_private_handle->fd, NULL);
+
close(file_private_handle->fd);
}
@@ -326,6 +331,7 @@ static gboolean file_read(gpointer handle, gpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -339,6 +345,7 @@ static gboolean file_read(gpointer handle, gpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -441,6 +448,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -454,6 +462,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -495,6 +504,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer,
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
if(byteswritten!=NULL) {
@@ -575,6 +585,7 @@ static gboolean file_flush(gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -584,6 +595,7 @@ static gboolean file_flush(gpointer handle)
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -591,10 +603,11 @@ static gboolean file_flush(gpointer handle)
if (ret==-1) {
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
- ": write of handle %p fd %d error: %s", handle,
+ ": fsync of handle %p fd %d error: %s", handle,
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -617,6 +630,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_SET_FILE_POINTER);
}
@@ -627,6 +641,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(INVALID_SET_FILE_POINTER);
}
@@ -646,6 +661,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
method);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(INVALID_SET_FILE_POINTER);
}
@@ -658,7 +674,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
movedistance);
#endif
} else {
- offset=((gint64) *highmovedistance << 32) | movedistance;
+ offset=((gint64) *highmovedistance << 32) | (unsigned long)movedistance;
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION ": setting offset to %lld 0x%llx (high %d 0x%x, low %d 0x%x)", offset, offset, *highmovedistance, *highmovedistance, movedistance, movedistance);
@@ -688,6 +704,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance,
handle, file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_SET_FILE_POINTER);
}
@@ -737,6 +754,7 @@ static gboolean file_setendoffile(gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -746,6 +764,7 @@ static gboolean file_setendoffile(gpointer handle)
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -763,6 +782,7 @@ static gboolean file_setendoffile(gpointer handle)
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
size=statbuf.st_size;
@@ -775,6 +795,7 @@ static gboolean file_setendoffile(gpointer handle)
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -793,6 +814,7 @@ static gboolean file_setendoffile(gpointer handle)
strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
}
@@ -812,6 +834,7 @@ static gboolean file_setendoffile(gpointer handle)
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -833,6 +856,7 @@ static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_FILE_SIZE);
}
@@ -843,6 +867,7 @@ static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(INVALID_FILE_SIZE);
}
@@ -854,6 +879,7 @@ static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_FILE_SIZE);
}
@@ -895,6 +921,7 @@ static gboolean file_getfiletime(gpointer handle, WapiFileTime *create_time,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -904,6 +931,7 @@ static gboolean file_getfiletime(gpointer handle, WapiFileTime *create_time,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -915,6 +943,7 @@ static gboolean file_getfiletime(gpointer handle, WapiFileTime *create_time,
file_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -986,6 +1015,7 @@ static gboolean file_setfiletime(gpointer handle,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -995,6 +1025,7 @@ static gboolean file_setfiletime(gpointer handle,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -1005,6 +1036,7 @@ static gboolean file_setfiletime(gpointer handle,
file_private_handle->fd);
#endif
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -1019,12 +1051,25 @@ static gboolean file_setfiletime(gpointer handle,
file_private_handle->fd, strerror(errno));
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if(last_access!=NULL) {
access_ticks=((guint64)last_access->dwHighDateTime << 32) +
last_access->dwLowDateTime;
+ /* This is (time_t)0. We can actually go to INT_MIN,
+ * but this will do for now.
+ */
+ if (access_ticks < 116444736000000000ULL) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION
+ ": attempt to set access time too early");
+#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return(FALSE);
+ }
+
utbuf.actime=(access_ticks - 116444736000000000ULL) / 10000000;
} else {
utbuf.actime=statbuf.st_atime;
@@ -1033,6 +1078,18 @@ static gboolean file_setfiletime(gpointer handle,
if(last_write!=NULL) {
write_ticks=((guint64)last_write->dwHighDateTime << 32) +
last_write->dwLowDateTime;
+ /* This is (time_t)0. We can actually go to INT_MIN,
+ * but this will do for now.
+ */
+ if (write_ticks < 116444736000000000ULL) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION
+ ": attempt to set write time too early");
+#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return(FALSE);
+ }
+
utbuf.modtime=(write_ticks - 116444736000000000ULL) / 10000000;
} else {
utbuf.modtime=statbuf.st_mtime;
@@ -1055,6 +1112,7 @@ static gboolean file_setfiletime(gpointer handle,
#endif
g_free (name);
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
@@ -1073,6 +1131,7 @@ static void console_close_shared (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up console handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -1100,6 +1159,7 @@ static void console_close_private (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up console handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -1109,6 +1169,9 @@ static void console_close_private (gpointer handle)
console_private_handle->fd);
#endif
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (console_private_handle->fd, NULL);
+
close(console_private_handle->fd);
}
@@ -1132,6 +1195,7 @@ static gboolean console_read(gpointer handle, gpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up console handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -1145,6 +1209,7 @@ static gboolean console_read(gpointer handle, gpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -1160,6 +1225,7 @@ static gboolean console_read(gpointer handle, gpointer buffer,
console_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -1185,6 +1251,7 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up console handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -1198,6 +1265,7 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -1213,6 +1281,7 @@ static gboolean console_write(gpointer handle, gconstpointer buffer,
console_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
if(byteswritten!=NULL) {
@@ -1232,6 +1301,7 @@ static void pipe_close_shared (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up pipe handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -1259,6 +1329,7 @@ static void pipe_close_private (gpointer handle)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up pipe handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return;
}
@@ -1268,6 +1339,9 @@ static void pipe_close_private (gpointer handle)
pipe_private_handle->fd);
#endif
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (pipe_private_handle->fd, NULL);
+
close(pipe_private_handle->fd);
}
@@ -1291,6 +1365,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up pipe handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -1304,6 +1379,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -1325,6 +1401,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer,
pipe_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
@@ -1354,6 +1431,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up pipe handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -1367,6 +1445,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
@@ -1388,6 +1467,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer,
pipe_private_handle->fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
if(byteswritten!=NULL) {
@@ -1542,6 +1622,7 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
@@ -1552,6 +1633,7 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
": unicode conversion returned NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
@@ -1586,6 +1668,19 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
return(INVALID_HANDLE_VALUE);
}
+ if (fd >= _wapi_fd_offset_table_size) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": File descriptor is too big");
+#endif
+
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+
+ close (fd);
+ g_free (filename);
+
+ return(INVALID_HANDLE_VALUE);
+ }
+
ret = fstat (fd, &statbuf);
if (ret == -1) {
#ifdef DEBUG
@@ -1655,6 +1750,7 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
g_free (filename);
close (fd);
+ SetLastError (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
}
@@ -1669,10 +1765,13 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess,
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up file handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
close (fd);
goto cleanup;
}
- cf_ret = handle;
+
+ _wapi_handle_fd_offset_store (fd, handle);
+ cf_ret = GINT_TO_POINTER (fd);
file_private_handle->fd=fd;
file_private_handle->assigned=TRUE;
@@ -1725,6 +1824,7 @@ gboolean DeleteFile(const gunichar2 *name)
g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(FALSE);
}
@@ -1735,6 +1835,7 @@ gboolean DeleteFile(const gunichar2 *name)
": unicode conversion returned NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(FALSE);
}
@@ -1765,6 +1866,15 @@ gboolean MoveFile (const gunichar2 *name, const gunichar2 *dest_name)
{
gchar *utf8_name, *utf8_dest_name;
int result;
+
+ if(name==NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
@@ -1772,8 +1882,19 @@ gboolean MoveFile (const gunichar2 *name, const gunichar2 *dest_name)
g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
+
+ if(dest_name==NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ g_free (utf8_name);
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_dest_name = mono_unicode_to_external (dest_name);
if (utf8_dest_name == NULL) {
@@ -1782,6 +1903,7 @@ gboolean MoveFile (const gunichar2 *name, const gunichar2 *dest_name)
#endif
g_free (utf8_name);
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
@@ -1792,6 +1914,7 @@ gboolean MoveFile (const gunichar2 *name, const gunichar2 *dest_name)
if (result != 0 && errno == EXDEV) {
/* Try a copy to the new location, and delete the source */
if (CopyFile (name, dest_name, TRUE)==FALSE) {
+ /* CopyFile will set the error */
return(FALSE);
}
@@ -1837,6 +1960,15 @@ gboolean CopyFile (const gunichar2 *name, const gunichar2 *dest_name,
int remain, n;
struct stat st;
+ if(name==NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_src = mono_unicode_to_external (name);
if (utf8_src == NULL) {
#ifdef DEBUG
@@ -1847,6 +1979,16 @@ gboolean CopyFile (const gunichar2 *name, const gunichar2 *dest_name,
return(FALSE);
}
+ if(dest_name==NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ g_free (utf8_src);
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_dest = mono_unicode_to_external (dest_name);
if (utf8_dest == NULL) {
#ifdef DEBUG
@@ -1958,16 +2100,16 @@ gboolean CopyFile (const gunichar2 *name, const gunichar2 *dest_name,
}
static mono_once_t stdhandle_once=MONO_ONCE_INIT;
-static gpointer stdin_handle=NULL;
-static gpointer stdout_handle=NULL;
-static gpointer stderr_handle=NULL;
+static gpointer stdin_handle=INVALID_HANDLE_VALUE;
+static gpointer stdout_handle=INVALID_HANDLE_VALUE;
+static gpointer stderr_handle=INVALID_HANDLE_VALUE;
static gpointer stdhandle_create (int fd, const guchar *name)
{
struct _WapiHandle_file *file_handle;
struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
- gpointer handle, ret = NULL;
+ gpointer handle, ret = INVALID_HANDLE_VALUE;
int flags;
int thr_ret;
@@ -1991,6 +2133,7 @@ static gpointer stdhandle_create (int fd, const guchar *name)
fd, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_HANDLE_VALUE);
}
@@ -1998,7 +2141,8 @@ static gpointer stdhandle_create (int fd, const guchar *name)
if(handle==_WAPI_HANDLE_INVALID) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error creating file handle");
- return(NULL);
+ SetLastError (ERROR_GEN_FAILURE);
+ return(INVALID_HANDLE_VALUE);
}
pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
@@ -2012,9 +2156,13 @@ static gpointer stdhandle_create (int fd, const guchar *name)
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error looking up console handle %p", handle);
+ SetLastError (ERROR_INVALID_HANDLE);
goto cleanup;
}
- ret = handle;
+
+ /* We know this is fd 0, 1 or 2 */
+ _wapi_handle_fd_offset_store (fd, handle);
+ ret = GINT_TO_POINTER (fd);
file_private_handle->fd=fd;
file_private_handle->assigned=TRUE;
@@ -2081,11 +2229,17 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
": unknown standard handle type");
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
+ if (handle == INVALID_HANDLE_VALUE) {
+ SetLastError (ERROR_NO_MORE_FILES);
+ return(INVALID_HANDLE_VALUE);
+ }
+
/* Add a reference to this handle */
- _wapi_handle_ref (handle);
+ _wapi_handle_ref (_wapi_handle_fd_offset_to_handle (handle));
return(handle);
}
@@ -2117,12 +2271,21 @@ gpointer GetStdHandle(WapiStdHandle stdhandle)
* read due to an attempt to read past the end of the file), %FALSE on
* error.
*/
-gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes,
+gboolean ReadFile(gpointer fd_handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].readfile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2155,12 +2318,21 @@ gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes,
*
* Return value: %TRUE if the write succeeds, %FALSE on error.
*/
-gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes,
+gboolean WriteFile(gpointer fd_handle, gconstpointer buffer, guint32 numbytes,
guint32 *byteswritten, WapiOverlapped *overlapped)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].writefile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2178,11 +2350,20 @@ gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes,
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
-gboolean FlushFileBuffers(gpointer handle)
+gboolean FlushFileBuffers(gpointer fd_handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].flushfile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2199,11 +2380,20 @@ gboolean FlushFileBuffers(gpointer handle)
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
-gboolean SetEndOfFile(gpointer handle)
+gboolean SetEndOfFile(gpointer fd_handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].setendoffile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2239,13 +2429,22 @@ gboolean SetEndOfFile(gpointer handle)
* If @highmovedistance is not %NULL, the high 32 bits of the new file
* pointer are stored there. On failure, %INVALID_SET_FILE_POINTER.
*/
-guint32 SetFilePointer(gpointer handle, gint32 movedistance,
+guint32 SetFilePointer(gpointer fd_handle, gint32 movedistance,
gint32 *highmovedistance, WapiSeekMethod method)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_SET_FILE_POINTER);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].seek==NULL) {
- return(FALSE);
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_SET_FILE_POINTER);
}
return(io_ops[type].seek (handle, movedistance, highmovedistance,
@@ -2263,11 +2462,20 @@ guint32 SetFilePointer(gpointer handle, gint32 movedistance,
* %FILE_TYPE_CHAR - @handle is a character device, such as a console.
* %FILE_TYPE_PIPE - @handle is a named or anonymous pipe.
*/
-WapiFileType GetFileType(gpointer handle)
+WapiFileType GetFileType(gpointer fd_handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FILE_TYPE_UNKNOWN);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].getfiletype==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FILE_TYPE_UNKNOWN);
}
@@ -2290,12 +2498,21 @@ WapiFileType GetFileType(gpointer handle)
* @highsize is non-%NULL then the high 32 bits of the file size are
* stored here. On failure %INVALID_FILE_SIZE is returned.
*/
-guint32 GetFileSize(gpointer handle, guint32 *highsize)
+guint32 GetFileSize(gpointer fd_handle, guint32 *highsize)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_FILE_SIZE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].getfilesize==NULL) {
- return(FALSE);
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_FILE_SIZE);
}
return(io_ops[type].getfilesize (handle, highsize));
@@ -2326,12 +2543,21 @@ guint32 GetFileSize(gpointer handle, guint32 *highsize)
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
-gboolean GetFileTime(gpointer handle, WapiFileTime *create_time,
+gboolean GetFileTime(gpointer fd_handle, WapiFileTime *create_time,
WapiFileTime *last_access, WapiFileTime *last_write)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].getfiletime==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2362,13 +2588,22 @@ gboolean GetFileTime(gpointer handle, WapiFileTime *create_time,
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
-gboolean SetFileTime(gpointer handle, const WapiFileTime *create_time,
+gboolean SetFileTime(gpointer fd_handle, const WapiFileTime *create_time,
const WapiFileTime *last_access,
const WapiFileTime *last_write)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].setfiletime==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
@@ -2415,6 +2650,7 @@ gboolean FileTimeToSystemTime(const WapiFileTime *file_time,
g_message(G_GNUC_PRETTY_FUNCTION ": system_time NULL");
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
@@ -2430,6 +2666,7 @@ gboolean FileTimeToSystemTime(const WapiFileTime *file_time,
g_message(G_GNUC_PRETTY_FUNCTION ": file_time too big");
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
@@ -2766,6 +3003,7 @@ gpointer FindFirstFile (const gunichar2 *pattern, WapiFindData *find_data)
g_free (dir_part);
g_free (entry_part);
g_free (utf8_pattern);
+ SetLastError (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
}
@@ -2786,6 +3024,7 @@ gpointer FindFirstFile (const gunichar2 *pattern, WapiFindData *find_data)
entry_part = NULL;
g_free (utf8_pattern);
utf8_pattern = NULL;
+ SetLastError (ERROR_INVALID_HANDLE);
goto cleanup;
}
@@ -3054,12 +3293,22 @@ gboolean CreateDirectory (const gunichar2 *name, WapiSecurityAttributes *securit
struct stat buf;
guint32 attrs;
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
@@ -3106,6 +3355,15 @@ gboolean RemoveDirectory (const gunichar2 *name)
{
gchar *utf8_name;
int result;
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
@@ -3113,6 +3371,7 @@ gboolean RemoveDirectory (const gunichar2 *name)
g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
@@ -3140,6 +3399,15 @@ guint32 GetFileAttributes (const gunichar2 *name)
struct stat buf;
int result;
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
@@ -3186,8 +3454,18 @@ gboolean GetFileAttributesEx (const gunichar2 *name, WapiGetFileExInfoLevels lev
g_message (G_GNUC_PRETTY_FUNCTION ": info level %d not supported.", level);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
@@ -3254,8 +3532,26 @@ extern gboolean SetFileAttributes (const gunichar2 *name, guint32 attrs)
* Currently we only handle one *internal* case, with a value that is
* not standard: 0x80000000, which means `set executable bit'
*/
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
+ if (utf8_name == NULL) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return FALSE;
+ }
+
result = stat (utf8_name, &buf);
if (result != 0) {
g_free (utf8_name);
@@ -3367,10 +3663,14 @@ extern gboolean SetCurrentDirectory (const gunichar2 *path)
return result;
}
-int _wapi_file_handle_to_fd (gpointer handle)
+/* When we're confident there are no more bugs in the fd->handle
+ * mapping, this can be replaced as a no-op: GPOINTER_TO_INT(fd_handle) == fd
+ */
+int _wapi_file_handle_to_fd (gpointer fd_handle)
{
struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
#ifdef DEBUG
g_message (G_GNUC_PRETTY_FUNCTION ": looking up fd for %p", handle);
@@ -3389,6 +3689,7 @@ int _wapi_file_handle_to_fd (gpointer handle)
g_message (G_GNUC_PRETTY_FUNCTION
": returning -1");
#endif
+ SetLastError (ERROR_INVALID_HANDLE);
return(-1);
}
}
@@ -3399,6 +3700,8 @@ int _wapi_file_handle_to_fd (gpointer handle)
file_private_handle->fd);
#endif
+ g_assert (file_private_handle->fd == GPOINTER_TO_INT (fd_handle));
+
return(file_private_handle->fd);
}
@@ -3434,6 +3737,20 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
_wapi_set_last_error_from_errno ();
return(FALSE);
}
+
+ if (filedes[0] >= _wapi_fd_offset_table_size ||
+ filedes[1] >= _wapi_fd_offset_table_size) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": File descriptor is too big");
+#endif
+
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+
+ close (filedes[0]);
+ close (filedes[1]);
+
+ return(FALSE);
+ }
/* filedes[0] is open for reading, filedes[1] for writing */
@@ -3443,6 +3760,8 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
": error creating pipe read handle");
close (filedes[0]);
close (filedes[1]);
+ SetLastError (ERROR_GEN_FAILURE);
+
return(FALSE);
}
@@ -3458,6 +3777,7 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
g_warning (G_GNUC_PRETTY_FUNCTION ": error looking up pipe handle %p", read_handle);
close (filedes[0]);
close (filedes[1]);
+ SetLastError (ERROR_INVALID_HANDLE);
goto cleanup;
}
@@ -3469,6 +3789,8 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
close (filedes[0]);
close (filedes[1]);
+ SetLastError (ERROR_GEN_FAILURE);
+
goto cleanup;
}
@@ -3487,6 +3809,7 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
close (filedes[0]);
close (filedes[1]);
+ SetLastError (ERROR_INVALID_HANDLE);
goto write_cleanup;
}
cp_ret = TRUE;
@@ -3495,18 +3818,18 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
pipe_read_private_handle->assigned=TRUE;
pipe_read_handle->fileaccess=GENERIC_READ;
- *readpipe=read_handle;
+ _wapi_handle_fd_offset_store (filedes[0], read_handle);
+ *readpipe=GINT_TO_POINTER (filedes[0]);
pipe_write_private_handle->fd=filedes[1];
pipe_write_private_handle->assigned=TRUE;
pipe_write_handle->fileaccess=GENERIC_WRITE;
- *writepipe=write_handle;
+ _wapi_handle_fd_offset_store (filedes[1], write_handle);
+ *writepipe=GINT_TO_POINTER (filedes[1]);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Returning pipe: read handle %p, write handle %p",
- read_handle, write_handle);
+ g_message (G_GNUC_PRETTY_FUNCTION ": Returning pipe: read handle %p (fd %d), write handle %p (fd %d)", read_handle, filedes[0], write_handle, filedes[1]);
#endif
write_cleanup:
@@ -3579,7 +3902,7 @@ guint32 GetTempPath (guint32 len, gunichar2 *buf)
}
gboolean
-_wapi_io_add_callback (gpointer handle,
+_wapi_io_add_callback (gpointer fd_handle,
WapiOverlappedCB callback,
guint64 flags G_GNUC_UNUSED)
{
@@ -3588,6 +3911,12 @@ _wapi_io_add_callback (gpointer handle,
gboolean ok;
int thr_ret;
gboolean ret = FALSE;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
(gpointer *) &file_handle,
@@ -3761,13 +4090,19 @@ static gboolean _wapi_unlock_file_region (int fd, off_t offset, off_t length)
return(TRUE);
}
-gboolean LockFile (gpointer handle, guint32 offset_low, guint32 offset_high,
+gboolean LockFile (gpointer fd_handle, guint32 offset_low, guint32 offset_high,
guint32 length_low, guint32 length_high)
{
struct _WapiHandle_file *file_handle;
struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
off_t offset, length;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
(gpointer *)&file_handle,
@@ -3813,13 +4148,20 @@ gboolean LockFile (gpointer handle, guint32 offset_low, guint32 offset_high,
length));
}
-gboolean UnlockFile (gpointer handle, guint32 offset_low, guint32 offset_high,
- guint32 length_low, guint32 length_high)
+gboolean UnlockFile (gpointer fd_handle, guint32 offset_low,
+ guint32 offset_high, guint32 length_low,
+ guint32 length_high)
{
struct _WapiHandle_file *file_handle;
struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
off_t offset, length;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
(gpointer *)&file_handle,
diff --git a/mono/io-layer/mutexes.c b/mono/io-layer/mutexes.c
index ee736aac2c2..ee10921578a 100644
--- a/mono/io-layer/mutexes.c
+++ b/mono/io-layer/mutexes.c
@@ -23,9 +23,8 @@
#undef DEBUG
/* This is used to serialise mutex creation when names are given
- * (FIXME: make it process-shared)
*/
-static mono_mutex_t named_mutex_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t named_mutex_mutex;
static void mutex_close_shared (gpointer handle);
static void mutex_signal(gpointer handle);
@@ -44,6 +43,23 @@ static mono_once_t mutex_ops_once=MONO_ONCE_INIT;
static void mutex_ops_init (void)
{
+ int thr_ret;
+#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED != -1
+ pthread_mutexattr_t mutex_shared_attr;
+
+ thr_ret = mono_mutexattr_init (&mutex_shared_attr);
+ g_assert (thr_ret == 0);
+
+ thr_ret = mono_mutexattr_setpshared (&mutex_shared_attr,
+ PTHREAD_PROCESS_SHARED);
+ g_assert (thr_ret == 0);
+
+ thr_ret = mono_mutex_init (&named_mutex_mutex, &mutex_shared_attr);
+ g_assert (thr_ret == 0);
+#else
+ thr_ret = mono_mutex_init (&named_mutex_mutex, NULL);
+#endif
+
_wapi_handle_register_capabilities (WAPI_HANDLE_MUTEX,
WAPI_HANDLE_CAP_WAIT |
WAPI_HANDLE_CAP_SIGNAL |
diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c
index 3f48f02af8e..25f165763ea 100644
--- a/mono/io-layer/sockets.c
+++ b/mono/io-layer/sockets.c
@@ -97,6 +97,9 @@ static void socket_close_private (gpointer handle)
g_ptr_array_remove_fast(sockets, GUINT_TO_POINTER (handle));
+ /* Blank out the mapping, to make catching errors easier */
+ _wapi_handle_fd_offset_store (socket_private_handle->fd, NULL);
+
do {
ret=close(socket_private_handle->fd);
}
@@ -205,20 +208,27 @@ int WSAGetLastError(void)
return(err);
}
-int closesocket(guint32 handle)
+int closesocket(guint32 fd_handle)
{
- _wapi_handle_unref (GUINT_TO_POINTER (handle));
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd_handle));
+
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ WSASetLastError (WSAENOTSOCK);
+ return(0);
+ }
+
+ _wapi_handle_unref (handle);
return(0);
}
-guint32 _wapi_accept(guint32 handle, struct sockaddr *addr,
- socklen_t *addrlen)
+guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
struct _WapiHandlePrivate_socket *new_socket_private_handle;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
gpointer new_handle;
gboolean ok;
- int fd;
+ int new_fd;
int thr_ret;
guint32 ret = INVALID_SOCKET;
@@ -227,21 +237,18 @@ guint32 _wapi_accept(guint32 handle, struct sockaddr *addr,
return(INVALID_SOCKET);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(INVALID_SOCKET);
}
do {
- fd=accept(socket_private_handle->fd, addr, addrlen);
+ new_fd=accept(fd, addr, addrlen);
}
- while (fd==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ while (new_fd==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
- if(fd==-1) {
+ if(new_fd==-1) {
gint errnum = errno;
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION ": accept error: %s",
@@ -254,10 +261,23 @@ guint32 _wapi_accept(guint32 handle, struct sockaddr *addr,
return(INVALID_SOCKET);
}
+ if (new_fd >= _wapi_fd_offset_table_size) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": File descriptor is too big");
+#endif
+
+ WSASetLastError (WSASYSCALLFAILURE);
+
+ close (new_fd);
+
+ return(INVALID_SOCKET);
+ }
+
new_handle=_wapi_handle_new (WAPI_HANDLE_SOCKET);
if(new_handle==_WAPI_HANDLE_INVALID) {
g_warning (G_GNUC_PRETTY_FUNCTION
": error creating socket handle");
+ WSASetLastError (ERROR_GEN_FAILURE);
return(INVALID_SOCKET);
}
@@ -270,12 +290,15 @@ guint32 _wapi_accept(guint32 handle, struct sockaddr *addr,
(gpointer *)&new_socket_private_handle);
if(ok==FALSE) {
g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ ": error looking up new socket handle %p",
+ new_handle);
goto cleanup;
}
- ret = GPOINTER_TO_UINT (new_handle);
+
+ _wapi_handle_fd_offset_store (new_fd, new_handle);
+ ret = new_fd;
- new_socket_private_handle->fd=fd;
+ new_socket_private_handle->fd=new_fd;
#ifdef DEBUG
g_message(G_GNUC_PRETTY_FUNCTION
@@ -291,27 +314,23 @@ cleanup:
return(ret);
}
-int _wapi_bind(guint32 handle, struct sockaddr *my_addr, socklen_t addrlen)
+int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
WSASetLastError(WSANOTINITIALISED);
return(SOCKET_ERROR);
}
-
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=bind(socket_private_handle->fd, my_addr, addrlen);
+ ret=bind(fd, my_addr, addrlen);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -326,11 +345,10 @@ int _wapi_bind(guint32 handle, struct sockaddr *my_addr, socklen_t addrlen)
return(ret);
}
-int _wapi_connect(guint32 handle, const struct sockaddr *serv_addr,
+int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
socklen_t addrlen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
gint errnum;
@@ -339,17 +357,14 @@ int _wapi_connect(guint32 handle, const struct sockaddr *serv_addr,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
do {
- ret=connect(socket_private_handle->fd, serv_addr, addrlen);
+ ret=connect(fd, serv_addr, addrlen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
@@ -361,11 +376,11 @@ int _wapi_connect(guint32 handle, const struct sockaddr *serv_addr,
errnum = errno;
- ret=setsockopt (socket_private_handle->fd, SOL_SOCKET,
- SO_BROADCAST, &true, sizeof(true));
+ ret=setsockopt (fd, SOL_SOCKET, SO_BROADCAST, &true,
+ sizeof(true));
if(ret==0) {
do {
- ret=connect (socket_private_handle->fd, serv_addr, addrlen);
+ ret=connect (fd, serv_addr, addrlen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
}
@@ -386,11 +401,9 @@ int _wapi_connect(guint32 handle, const struct sockaddr *serv_addr,
return(ret);
}
-int _wapi_getpeername(guint32 handle, struct sockaddr *name,
- socklen_t *namelen)
+int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -398,16 +411,13 @@ int _wapi_getpeername(guint32 handle, struct sockaddr *name,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=getpeername(socket_private_handle->fd, name, namelen);
+ ret=getpeername(fd, name, namelen);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -424,11 +434,9 @@ int _wapi_getpeername(guint32 handle, struct sockaddr *name,
return(ret);
}
-int _wapi_getsockname(guint32 handle, struct sockaddr *name,
- socklen_t *namelen)
+int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -436,16 +444,13 @@ int _wapi_getsockname(guint32 handle, struct sockaddr *name,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=getsockname(socket_private_handle->fd, name, namelen);
+ ret=getsockname(fd, name, namelen);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -462,11 +467,10 @@ int _wapi_getsockname(guint32 handle, struct sockaddr *name,
return(ret);
}
-int _wapi_getsockopt(guint32 handle, int level, int optname, void *optval,
+int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
socklen_t *optlen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -474,17 +478,13 @@ int _wapi_getsockopt(guint32 handle, int level, int optname, void *optval,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=getsockopt(socket_private_handle->fd, level, optname, optval,
- optlen);
+ ret=getsockopt(fd, level, optname, optval, optlen);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -501,10 +501,9 @@ int _wapi_getsockopt(guint32 handle, int level, int optname, void *optval,
return(ret);
}
-int _wapi_listen(guint32 handle, int backlog)
+int _wapi_listen(guint32 fd, int backlog)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -512,16 +511,13 @@ int _wapi_listen(guint32 handle, int backlog)
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=listen(socket_private_handle->fd, backlog);
+ ret=listen(fd, backlog);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -538,19 +534,18 @@ int _wapi_listen(guint32 handle, int backlog)
return(0);
}
-int _wapi_recv(guint32 handle, void *buf, size_t len, int recv_flags)
+int _wapi_recv(guint32 fd, void *buf, size_t len, int recv_flags)
{
- return(_wapi_recvfrom(handle, buf, len, recv_flags, NULL, 0));
+ return(_wapi_recvfrom(fd, buf, len, recv_flags, NULL, 0));
}
-int _wapi_recvfrom(guint32 handle, void *buf, size_t len, int recv_flags,
+int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
struct sockaddr *from, socklen_t *fromlen)
{
#ifndef HAVE_MSG_NOSIGNAL
void (*old_sigpipe)(int); // old SIGPIPE handler
#endif
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -558,26 +553,22 @@ int _wapi_recvfrom(guint32 handle, void *buf, size_t len, int recv_flags,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
#ifdef HAVE_MSG_NOSIGNAL
do {
- ret=recvfrom(socket_private_handle->fd, buf, len, recv_flags | MSG_NOSIGNAL, from,
+ ret=recvfrom(fd, buf, len, recv_flags | MSG_NOSIGNAL, from,
fromlen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
#else
old_sigpipe = signal(SIGPIPE, SIG_IGN);
do {
- ret=recvfrom(socket_private_handle->fd, buf, len, recv_flags, from,
- fromlen);
+ ret=recvfrom(fd, buf, len, recv_flags, from, fromlen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
signal(SIGPIPE, old_sigpipe);
@@ -598,13 +589,12 @@ int _wapi_recvfrom(guint32 handle, void *buf, size_t len, int recv_flags,
return(ret);
}
-int _wapi_send(guint32 handle, const void *msg, size_t len, int send_flags)
+int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
{
#ifndef HAVE_MSG_NOSIGNAL
void (*old_sigpipe)(int); // old SIGPIPE handler
#endif
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -612,24 +602,21 @@ int _wapi_send(guint32 handle, const void *msg, size_t len, int send_flags)
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
#ifdef HAVE_MSG_NOSIGNAL
do {
- ret=send(socket_private_handle->fd, msg, len, send_flags | MSG_NOSIGNAL);
+ ret=send(fd, msg, len, send_flags | MSG_NOSIGNAL);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
#else
old_sigpipe = signal(SIGPIPE, SIG_IGN);
do {
- ret=send(socket_private_handle->fd, msg, len, send_flags);
+ ret=send(fd, msg, len, send_flags);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
signal(SIGPIPE, old_sigpipe);
@@ -649,14 +636,13 @@ int _wapi_send(guint32 handle, const void *msg, size_t len, int send_flags)
return(ret);
}
-int _wapi_sendto(guint32 handle, const void *msg, size_t len, int send_flags,
+int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
const struct sockaddr *to, socklen_t tolen)
{
#ifndef HAVE_MSG_NOSIGNAL
void (*old_sigpipe)(int); // old SIGPIPE handler
#endif
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -664,24 +650,21 @@ int _wapi_sendto(guint32 handle, const void *msg, size_t len, int send_flags,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
#ifdef HAVE_MSG_NOSIGNAL
do {
- ret=sendto(socket_private_handle->fd, msg, len, send_flags | MSG_NOSIGNAL, to, tolen);
+ ret=sendto(fd, msg, len, send_flags | MSG_NOSIGNAL, to, tolen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
#else
old_sigpipe = signal(SIGPIPE, SIG_IGN);
do {
- ret=sendto(socket_private_handle->fd, msg, len, send_flags, to, tolen);
+ ret=sendto(fd, msg, len, send_flags, to, tolen);
}
while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
signal(SIGPIPE, old_sigpipe);
@@ -701,11 +684,10 @@ int _wapi_sendto(guint32 handle, const void *msg, size_t len, int send_flags,
return(ret);
}
-int _wapi_setsockopt(guint32 handle, int level, int optname,
+int _wapi_setsockopt(guint32 fd, int level, int optname,
const void *optval, socklen_t optlen)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -713,17 +695,13 @@ int _wapi_setsockopt(guint32 handle, int level, int optname,
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=setsockopt(socket_private_handle->fd, level, optname, optval,
- optlen);
+ ret=setsockopt(fd, level, optname, optval, optlen);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -740,10 +718,9 @@ int _wapi_setsockopt(guint32 handle, int level, int optname,
return(ret);
}
-int _wapi_shutdown(guint32 handle, int how)
+int _wapi_shutdown(guint32 fd, int how)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -751,16 +728,13 @@ int _wapi_shutdown(guint32 handle, int how)
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
- ret=shutdown(socket_private_handle->fd, how);
+ ret=shutdown(fd, how);
if(ret==-1) {
gint errnum = errno;
#ifdef DEBUG
@@ -802,6 +776,18 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused, guint32 u
return(INVALID_SOCKET);
}
+
+ if (fd >= _wapi_fd_offset_table_size) {
+#ifdef DEBUG
+ g_message (G_GNUC_PRETTY_FUNCTION ": File descriptor is too big");
+#endif
+
+ WSASetLastError (WSASYSCALLFAILURE);
+ close (fd);
+
+ return(INVALID_SOCKET);
+ }
+
mono_once (&socket_ops_once, socket_ops_init);
@@ -824,7 +810,9 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused, guint32 u
": error looking up socket handle %p", handle);
goto cleanup;
}
- ret = GPOINTER_TO_UINT (handle);
+
+ _wapi_handle_fd_offset_store (fd, handle);
+ ret = fd;
socket_private_handle->fd=fd;
@@ -884,13 +872,12 @@ struct hostent *_wapi_gethostbyname(const char *hostname)
}
int
-WSAIoctl (guint32 handle, gint32 command,
- gchar *input, gint i_len,
- gchar *output, gint o_len, glong *written,
- void *unused1, void *unused2)
+WSAIoctl (guint32 fd, gint32 command,
+ gchar *input, gint i_len,
+ gchar *output, gint o_len, glong *written,
+ void *unused1, void *unused2)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
gchar *buffer = NULL;
@@ -899,12 +886,8 @@ WSAIoctl (guint32 handle, gint32 command,
return(SOCKET_ERROR);
}
- ok = _wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
-
- if (ok == FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return SOCKET_ERROR;
}
@@ -912,7 +895,7 @@ WSAIoctl (guint32 handle, gint32 command,
if (i_len > 0)
buffer = g_memdup (input, i_len);
- ret = ioctl (socket_private_handle->fd, command, buffer);
+ ret = ioctl (fd, command, buffer);
if (ret == -1) {
gint errnum = errno;
#ifdef DEBUG
@@ -941,10 +924,9 @@ WSAIoctl (guint32 handle, gint32 command,
return 0;
}
-int ioctlsocket(guint32 handle, gint32 command, gpointer arg)
+int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
int ret;
if(startup_count==0) {
@@ -952,11 +934,8 @@ int ioctlsocket(guint32 handle, gint32 command, gpointer arg)
return(SOCKET_ERROR);
}
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(SOCKET_ERROR);
}
@@ -976,19 +955,19 @@ int ioctlsocket(guint32 handle, gint32 command, gpointer arg)
* connect to return EINPROGRESS, but the ioctl doesn't seem to)
*/
if(command==FIONBIO) {
- ret=fcntl(socket_private_handle->fd, F_GETFL, 0);
+ ret=fcntl(fd, F_GETFL, 0);
if(ret!=-1) {
if(*(gboolean *)arg) {
ret &= ~O_NONBLOCK;
} else {
ret |= O_NONBLOCK;
}
- ret=fcntl(socket_private_handle->fd, F_SETFL, ret);
+ ret=fcntl(fd, F_SETFL, ret);
}
} else
#endif /* O_NONBLOCK */
{
- ret=ioctl(socket_private_handle->fd, command, arg);
+ ret=ioctl(fd, command, arg);
}
if(ret==-1) {
gint errnum = errno;
@@ -1036,55 +1015,43 @@ int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
return(ret);
}
-void _wapi_FD_CLR(guint32 handle, fd_set *set)
+void _wapi_FD_CLR(guint32 fd, fd_set *set)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return;
}
- FD_CLR(socket_private_handle->fd, set);
+ FD_CLR(fd, set);
}
-int _wapi_FD_ISSET(guint32 handle, fd_set *set)
+int _wapi_FD_ISSET(guint32 fd, fd_set *set)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return(0);
}
- return(FD_ISSET(socket_private_handle->fd, set));
+ return(FD_ISSET(fd, set));
}
-void _wapi_FD_SET(guint32 handle, fd_set *set)
+void _wapi_FD_SET(guint32 fd, fd_set *set)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (GUINT_TO_POINTER (fd));
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError(WSAENOTSOCK);
return;
}
- FD_SET(socket_private_handle->fd, set);
+ FD_SET(fd, set);
}
#ifdef USE_AIO
@@ -1119,29 +1086,23 @@ async_notifier (union sigval sig)
}
static gboolean
-do_aio_call (gboolean is_read, gpointer handle, gpointer buffer,
+do_aio_call (gboolean is_read, gpointer fd_handle, gpointer buffer,
guint32 numbytes, guint32 *out_bytes,
gpointer ares,
SocketAsyncCB callback)
{
- struct _WapiHandlePrivate_socket *socket_private_handle;
- gboolean ok;
- int fd;
+ gpointer handle = _wapi_handle_fd_offset_to_handle (fd_handle);
+ int fd = GPOINTER_TO_UINT (fd_handle);
struct aiocb *aio;
int result;
notifier_data_t *ndata;
- ok=_wapi_lookup_handle (GUINT_TO_POINTER (handle), WAPI_HANDLE_SOCKET,
- NULL, (gpointer *)&socket_private_handle);
- if (ok == FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up socket handle 0x%x", (guint) handle);
+ if (handle == NULL ||
+ _wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return FALSE;
}
- fd = socket_private_handle->fd;
-
ndata = g_new0 (notifier_data_t, 1);
aio = g_new0 (struct aiocb, 1);
ndata->ares = ares;
diff --git a/mono/io-layer/threads.c b/mono/io-layer/threads.c
index b9ddc6aa3dc..31c1176a12c 100644
--- a/mono/io-layer/threads.c
+++ b/mono/io-layer/threads.c
@@ -99,9 +99,7 @@ static void thread_close_private (gpointer handle)
thread_handle->thread->id);
#endif
- if(thread_handle->thread!=NULL) {
- _wapi_timed_thread_destroy (thread_handle->thread);
- }
+ thread_handle->thread=NULL;
}
static void thread_own (gpointer handle)
@@ -628,6 +626,10 @@ guint32 ResumeThread(gpointer handle)
return(0xFFFFFFFF);
}
+ if (thread_private_handle->thread == NULL) {
+ return(0xFFFFFFFF);
+ }
+
#ifdef WITH_INCLUDED_LIBGC
if (thread_private_handle->thread->suspend_count <= 1)
_wapi_timed_thread_resume (thread_private_handle->thread);
@@ -670,6 +672,10 @@ guint32 SuspendThread(gpointer handle)
return(0xFFFFFFFF);
}
+ if (thread_private_handle->thread == NULL) {
+ return(0xFFFFFFFF);
+ }
+
if (!thread_private_handle->thread->suspend_count) {
if (handle == current)
_wapi_timed_thread_suspend (thread_private_handle->thread);
diff --git a/mono/io-layer/timed-thread.c b/mono/io-layer/timed-thread.c
index c0d737862a2..6599e0660f3 100644
--- a/mono/io-layer/timed-thread.c
+++ b/mono/io-layer/timed-thread.c
@@ -254,6 +254,8 @@ int _wapi_timed_thread_join(TimedThread *thread, struct timespec *timeout,
if(exitstatus!=NULL) {
*exitstatus = thread->exitstatus;
}
+
+ _wapi_timed_thread_destroy (thread);
}
return(result);
}
diff --git a/mono/io-layer/wait.c b/mono/io-layer/wait.c
index e3d07b3a255..a236d17ed3e 100644
--- a/mono/io-layer/wait.c
+++ b/mono/io-layer/wait.c
@@ -354,9 +354,15 @@ static gboolean test_and_own (guint32 numobjects, gpointer *handles,
done = _wapi_handle_count_signalled_handles (numobjects, handles,
waitall, count, lowest);
if (done == TRUE) {
- for (i = 0; i < numobjects; i++) {
- if (_wapi_handle_issignalled (handles[i])) {
- _wapi_handle_ops_own (handles[i]);
+ if (waitall == TRUE) {
+ for (i = 0; i < numobjects; i++) {
+ if (_wapi_handle_issignalled (handles[i])) {
+ _wapi_handle_ops_own (handles[i]);
+ }
+ }
+ } else {
+ if (_wapi_handle_issignalled (handles[*lowest])) {
+ _wapi_handle_ops_own (handles[*lowest]);
}
}
}
diff --git a/mono/io-layer/wapi-private.h b/mono/io-layer/wapi-private.h
index 59ec8defe30..92e0682288a 100644
--- a/mono/io-layer/wapi-private.h
+++ b/mono/io-layer/wapi-private.h
@@ -35,7 +35,7 @@
/* Increment this whenever an incompatible change is made to the
* shared handle structure.
*/
-#define _WAPI_HANDLE_VERSION 1
+#define _WAPI_HANDLE_VERSION 3
typedef enum {
WAPI_HANDLE_UNUSED=0,
@@ -152,6 +152,7 @@ struct _WapiHandleShared_list
{
guchar daemon[MONO_SIZEOF_SUNPATH];
_wapi_daemon_status daemon_running;
+ guint32 fd_offset_table_size;
#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED != -1
mono_mutex_t signal_mutex;
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index 662605f6c5c..01280d3fe0a 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,177 @@
+2004-09-18 Martin Baulig <martin@ximian.com>
+
+ * mono-debug.c, debug-mono-symfile.c: Merged my locking changes
+ from HEAD.
+
+2004-09-17 Zoltan Varga <vargaz@freemail.hu>
+
+ * loader.c (mono_lookup_pinvoke_call): Add support for stdcall name
+ mangling.
+
+2004-09-16 Lluis Sanchez Gual <lluis@novell.com>
+
+ * locales.c: nullify the ICU_collator member of CompareInfo when it is
+ finalized. There where random SIGSEVs at program termination, when
+ an object being finalized was trying to do a string comparison and
+ the current culture was already finalized.
+
+2004-09-16 Zoltan Varga <vargaz@freemail.hu>
+
+ * appdomain.c (ves_icall_System_AppDomain_createDomain): Load all
+ assemblies from the parent. Fixes #65665.
+
+2004-09-14 Lluis Sanchez Gual <lluis@novell.com>
+
+ * object.c: Added a "done" flag to TypeInitializationLock. This avoids
+ false deadlock checks in class initialization.
+
+2004-09-09 Zoltan Varga <vargaz@freemail.hu>
+
+ * reflection.h reflection.c loader.c: Allow dynamic construction of
+ pinvoke methods. Fixes #65571.
+
+2004-09-08 Lluis Sanchez Gual <lluis@novell.com>
+
+ * object.c: In mono_message_invoke, fill the output parameter array after
+ calling the managed method (it was done before the call). This fixes
+ bug #59299.
+
+2004-09-08 Zoltan Varga <vargaz@freemail.hu>
+
+ * image.c (mono_image_close): Applied patch from
+ vasantha.paulraj@honeywell.com (Vasantha selvi). Fix crash when an
+ assembly is loaded multiple times from data.
+
+ * image.c (mono_image_open): Fix warning.
+
+2004-09-07 Zoltan Varga <vargaz@freemail.hu>
+
+ * reflection.c (mono_reflection_create_runtime_class): Initialize
+ klass->nested_classes. Fixes #61224.
+
+2004-09-06 Zoltan Varga <vargaz@freemail.hu>
+
+ * reflection.c (mono_param_get_objects): Initialize the default value
+ with DBNull.Value, not null. Fixes #62123.
+
+2004-09-01 Miguel de Icaza <miguel@ximian.com>
+
+ * marshal.c (mono_marshal_get_managed_wrapper): Remove FIXME and
+ throw an exception with a cute explanation.
+
+2004-09-06 Dick Porter <dick@ximian.com>
+
+ * process.c (ves_icall_System_Diagnostics_Process_Start_internal):
+ Close the new process's thread handle, as we don't use it. The
+ handle stays around forever otherwise.
+
+2004-09-05 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * assembly.c: provide more information when loading an assembly fails.
+
+2004-09-04 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * filewatcher.c: don't expect the development fam package to be
+ installed. If HAVE_KQUEUE return mode 3 to use the new kqueue
+ watcher. Patch by Geoff Norton.
+
+2004-09-02 Zoltan Varga <vargaz@freemail.hu>
+
+ * marshal.c (mono_marshal_alloc): Return a valid pointer on size 0
+ as well.
+
+2004-08-28 Ben Maurer <bmaurer@users.sourceforge.net>
+
+ * gc.c: actually enable paolo's patch to make GC warnings
+ use the trace api.
+
+2004-08-23 Zoltan Varga <vargaz@freemail.hu>
+
+ * metadata.c (mono_metadata_parse_type): Alloc pinned, byref and
+ custom modifiers to be in any order. Fixes #61990.
+
+Thu Aug 5 17:11:44 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * reflection.c: fix to deal with object[] arrays in custom ctors
+ (bug #62550).
+
+Tue Aug 3 17:54:17 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * gc.c: make GC warning messages use the trace API, they are just
+ noise to most of the users.
+
+Tue Aug 3 16:40:17 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * gc.c, object.h: mono_gc_handle_*() interface and
+ AddrOfPinnedObject fixes. GC handle support even without GC.
+
+Fri Jul 30 16:49:05 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * object.c: always create an object if null is passed
+ to Invoke() where a valuetype is expected.
+
+2004-07-29 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * appdomain.c: hack to build correctly the private bin path on windows.
+ Fixes bug #61991.
+
+2004-07-28 Dick Porter <dick@ximian.com>
+
+ * socket-io.c
+ (ves_icall_System_Net_Sockets_Socket_RecvFrom_internal): Check
+ returned sockaddr size before creating the remote address object.
+ Patch by Nick Vaughan (dev@6wardlaw.freeserve.co.uk), fixes bug
+ 61608.
+
+2004-07-28 Dick Porter <dick@ximian.com>
+
+ * locales.c (string_invariant_compare_char): Fix invariant char
+ compares between upper and lower cases. Fixes bug 61458.
+
+Tue Jul 27 15:58:19 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * debug-mono-symfile.c: fix one more endianess issue, from a patch
+ by Geoff Norton (<gnorton@customerdna.com>).
+
+Tue Jul 27 15:47:17 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * class.c: fix class loads for pointer types (typeof(int) !=
+ typeof(int*)).
+
+2004-07-24 Martin Baulig <martin@ximian.com>
+
+ * reflection.c (mono_image_get_type_info): Only write a class
+ layout entry if we actually have a size or a packing size.
+
+2004-07-13 Peter Williams <peter@newton.cx>
+
+ * process.c (complete_path): Make sure we don't attempt to execute
+ directories.
+
+2004-07-11 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * debug-helpers.c: undo my previous patch and fixed the real issue in
+ ../mini/exceptions-x86.c
+
+2004-07-11 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * debug-helpers.c: prevent SIGSEGV. It happened running xsp on monodoc
+ when no HOME env. variable was set and a NullRef was thrown in a .cctor
+ called from other .cctors.
+
+2004-07-09 Dick Porter <dick@ximian.com>
+
+ * locales.c (ves_icall_System_String_InternalReplace_Str_Comp):
+ Don't do any more processing if the matched length was 0. It was
+ increasing the size of the string before. Fixes bug 61167.
+
+2004-07-09 Dick Porter <dick@ximian.com>
+
+ * socket-io.h:
+ * socket-io.c
+ (ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal):
+ Add support for SO_PEERCRED if its available.
+
2004-07-03 Zoltan Varga <vargaz@freemail.hu>
* marshal.c: Fix managed->native stringbuilder marshalling. Implement
@@ -10918,4 +11092,3 @@ Tue Jul 3 18:33:32 CEST 2001 Paolo Molaro <lupus@ximian.com>
Beta2.
* mono/metadata/assembly.c (load_metadata_ptrs): Fix for Beta2
-
diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c
index a917a9ecd19..688265a1eec 100644
--- a/mono/metadata/appdomain.c
+++ b/mono/metadata/appdomain.c
@@ -44,6 +44,9 @@ mono_domain_assembly_preload (MonoAssemblyName *aname,
static void
mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data);
+static void
+add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass);
+
static MonoMethod *
look_for_method_by_name (MonoClass *klass, const gchar *name);
@@ -357,10 +360,16 @@ ves_icall_System_AppDomain_getCurDomain ()
return add->domain;
}
+static void
+add_assembly_to_domain (gpointer key, gpointer value, gpointer user_data)
+{
+ add_assemblies_to_domain ((MonoDomain*)user_data, (MonoAssembly*)value);
+}
+
MonoAppDomain *
ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
{
- /*MonoDomain *domain = mono_domain_get (); */
+ MonoDomain *domain = mono_domain_get ();
MonoClass *adclass;
MonoAppDomain *ad;
MonoDomain *data;
@@ -381,7 +390,10 @@ ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomai
mono_context_init (data);
- /* FIXME: what to do next ? */
+ /* The new appdomain should have all assemblies loaded */
+ mono_domain_lock (domain);
+ g_hash_table_foreach (domain->assemblies, add_assembly_to_domain, data);
+ mono_domain_unlock (domain);
return ad;
}
@@ -547,9 +559,17 @@ reduce_path (const gchar *dirname)
for (tmp = list; tmp; tmp = tmp->next) {
gchar *data = (gchar *) tmp->data;
- if (data && *data)
- g_string_append_printf (result, "%c%s", G_DIR_SEPARATOR,
- (char *) tmp->data);
+ if (data && *data) {
+#ifdef PLATFORM_WIN32
+ if (result->len == 0)
+ g_string_append_printf (result, "%s\\", data);
+ else if (result->str [result->len - 1] == '\\')
+ g_string_append_printf (result, "%s", data);
+ else
+#endif
+ g_string_append_printf (result, "%c%s",
+ G_DIR_SEPARATOR, data);
+ }
}
res = result->str;
diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
index 2ae0d0eef7b..a0ec7467f38 100644
--- a/mono/metadata/assembly.c
+++ b/mono/metadata/assembly.c
@@ -388,6 +388,15 @@ mono_assembly_load_references (MonoImage *image, MonoImageOpenStatus *status)
image->name, aname.name);
} else {
+ char *extra_msg = g_strdup ("");
+
+ if (*status == MONO_IMAGE_ERROR_ERRNO) {
+ extra_msg = g_strdup_printf ("System error: %s\n", strerror (errno));
+ } else if (*status == MONO_IMAGE_MISSING_ASSEMBLYREF) {
+ extra_msg = g_strdup ("Cannot find an assembly referenced from this one.\n");
+ } else if (*status == MONO_IMAGE_IMAGE_INVALID) {
+ extra_msg = g_strdup ("The file exists but is not a valid assembly.\n");
+ }
for (j = 0; j < i; j++)
mono_assembly_close (references [j]);
@@ -396,11 +405,12 @@ mono_assembly_load_references (MonoImage *image, MonoImageOpenStatus *status)
g_warning ("Could not find assembly %s, references from %s (assemblyref_index=%d)\n"
" Major/Minor: %d,%d\n"
" Build: %d,%d\n"
- " Token: %s\n",
+ " Token: %s\n%s",
aname.name, image->name, i,
aname.major, aname.minor, aname.build, aname.revision,
- aname.public_key_token);
+ aname.public_key_token, extra_msg);
*status = MONO_IMAGE_MISSING_ASSEMBLYREF;
+ g_free (extra_msg);
return;
}
}
diff --git a/mono/metadata/class.c b/mono/metadata/class.c
index 7f434b5c734..2814e47d255 100644
--- a/mono/metadata/class.c
+++ b/mono/metadata/class.c
@@ -2124,7 +2124,7 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec,
class = mono_array_class_get (type->data.klass, 1);
break;
case MONO_TYPE_PTR:
- class = mono_class_from_mono_type (type->data.type);
+ class = mono_ptr_class_get (type->data.type);
break;
case MONO_TYPE_GENERICINST:
g_assert (type->data.generic_inst->klass);
diff --git a/mono/metadata/debug-mono-symfile.c b/mono/metadata/debug-mono-symfile.c
index 4f39e6827f1..a44c2748e18 100644
--- a/mono/metadata/debug-mono-symfile.c
+++ b/mono/metadata/debug-mono-symfile.c
@@ -107,17 +107,21 @@ mono_debug_open_mono_symbol_file (MonoDebugHandle *handle, gboolean create_symfi
{
MonoSymbolFile *symfile;
+ mono_loader_lock ();
symfile = g_new0 (MonoSymbolFile, 1);
symfile->raw_contents = open_symfile (handle->image, &symfile->raw_contents_size);
- if (load_symfile (handle, symfile))
+ if (load_symfile (handle, symfile)) {
+ mono_loader_unlock ();
return symfile;
- else if (!create_symfile) {
+ } else if (!create_symfile) {
mono_debug_close_mono_symbol_file (symfile);
+ mono_loader_unlock ();
return NULL;
}
+ mono_loader_unlock ();
return symfile;
}
@@ -127,16 +131,18 @@ mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile)
if (!symfile)
return;
+ mono_loader_lock ();
if (symfile->method_hash)
g_hash_table_destroy (symfile->method_hash);
g_free (symfile);
+ mono_loader_unlock ();
}
static gchar *
read_string (const char *ptr)
{
- int len = *((guint32 *) ptr);
+ int len = read32 (ptr);
ptr += sizeof(guint32);
return g_filename_from_utf8 (ptr, len, NULL, NULL, NULL);
}
@@ -151,12 +157,17 @@ mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, gu
const char *ptr;
int i;
- if (!symfile->method_hash)
+ mono_loader_lock ();
+ if (!symfile->method_hash) {
+ mono_loader_unlock ();
return NULL;
+ }
minfo = g_hash_table_lookup (symfile->method_hash, method);
- if (!minfo)
+ if (!minfo) {
+ mono_loader_unlock ();
return NULL;
+ }
if (read32(&(minfo->entry->_source_index))) {
int offset = read32(&(symfile->offset_table->_source_table_offset)) +
@@ -176,6 +187,7 @@ mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, gu
if (line_number) {
*line_number = read32(&(lne->_row));
+ mono_loader_unlock ();
if (source_file)
return source_file;
else
@@ -183,11 +195,16 @@ mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, gu
} else if (source_file) {
gchar *retval = g_strdup_printf ("%s:%d", source_file, read32(&(lne->_row)));
g_free (source_file);
+ mono_loader_unlock ();
return retval;
- } else
- return g_strdup_printf ("%d", read32(&(lne->_row)));
+ } else {
+ gchar* retval = g_strdup_printf ("%d", read32(&(lne->_row)));
+ mono_loader_unlock ();
+ return retval;
+ }
}
+ mono_loader_unlock ();
return NULL;
}
@@ -233,6 +250,7 @@ mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
if (handle->image != mono_class_get_image (mono_method_get_class (method)))
return NULL;
+ mono_loader_lock ();
first_ie = (MonoSymbolFileMethodIndexEntry *)
(symfile->raw_contents + read32(&(symfile->offset_table->_method_table_offset)));
@@ -240,8 +258,10 @@ mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
read32(&(symfile->offset_table->_method_count)),
sizeof (MonoSymbolFileMethodIndexEntry), compare_method);
- if (!ie)
+ if (!ie) {
+ mono_loader_unlock ();
return NULL;
+ }
me = (MonoSymbolFileMethodEntry *) (symfile->raw_contents + read32(&(ie->_file_offset)));
@@ -256,5 +276,6 @@ mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
g_hash_table_insert (symfile->method_hash, method, minfo);
+ mono_loader_unlock ();
return minfo;
}
diff --git a/mono/metadata/filewatcher.c b/mono/metadata/filewatcher.c
index 6210dc6b1f8..731eb3a1ad2 100644
--- a/mono/metadata/filewatcher.c
+++ b/mono/metadata/filewatcher.c
@@ -89,21 +89,26 @@ static int (*FAMNextEvent) (gpointer, gpointer);
gint
ves_icall_System_IO_FSW_SupportsFSW (void)
{
+#if HAVE_KQUEUE
+ return 3;
+#else
GModule *fam_module;
+ gchar *filename;
MONO_ARCH_SAVE_REGS;
- fam_module = g_module_open ("libfam", G_MODULE_BIND_LAZY);
- if (fam_module == NULL) {
+ filename = g_module_build_path (NULL, "libfam.so.0");
+ fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
+ g_free (filename);
+ if (fam_module == NULL)
return 0;
- }
-
g_module_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
if (FAMNextEvent == NULL)
return 0;
return 2;
+#endif
}
gpointer
diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c
index 4695c8c1a2a..3a9db3a1c62 100644
--- a/mono/metadata/gc.c
+++ b/mono/metadata/gc.c
@@ -16,6 +16,7 @@
#include <mono/metadata/exception.h>
#include <mono/metadata/domain-internals.h>
#include <mono/metadata/class-internals.h>
+#include <mono/utils/mono-logger.h>
#define GC_I_HIDE_POINTERS
#include <mono/os/gc_wrapper.h>
@@ -347,13 +348,17 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
/* Indexes start from 1 since 0 means the handle is not allocated */
idx = ++next_handle;
if (idx >= array_size) {
-#if HAVE_BOEHM_GC
gpointer *new_array;
guint8 *new_type_array;
if (!array_size)
array_size = 16;
+#if HAVE_BOEHM_GC
new_array = GC_MALLOC (sizeof (gpointer) * (array_size * 2));
new_type_array = GC_MALLOC (sizeof (guint8) * (array_size * 2));
+#else
+ new_array = g_malloc0 (sizeof (gpointer) * (array_size * 2));
+ new_type_array = g_malloc0 (sizeof (guint8) * (array_size * 2));
+#endif
if (gc_handles) {
int i;
memcpy (new_array, gc_handles, sizeof (gpointer) * array_size);
@@ -370,20 +375,22 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
#else
if (((gulong)new_array [i]) & 0x1) {
#endif
+#if HAVE_BOEHM_GC
if (gc_handles [i] != (gpointer)-1)
GC_unregister_disappearing_link (&(gc_handles [i]));
if (new_array [i] != (gpointer)-1)
GC_GENERAL_REGISTER_DISAPPEARING_LINK (&(new_array [i]), REVEAL_POINTER (new_array [i]));
+#endif
}
}
}
array_size *= 2;
+#ifndef HAVE_BOEHM_GC
+ g_free (gc_handles);
+ g_free (gc_handle_types);
+#endif
gc_handles = new_array;
gc_handle_types = new_type_array;
-#else
- LeaveCriticalSection (&handle_section);
- mono_raise_exception (mono_get_exception_execution_engine ("No GCHandle support built-in"));
-#endif
}
/* resuse the type from the old target */
@@ -399,9 +406,6 @@ ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint
#if HAVE_BOEHM_GC
if (gc_handles [idx] != (gpointer)-1)
GC_GENERAL_REGISTER_DISAPPEARING_LINK (&(gc_handles [idx]), obj);
-#else
- LeaveCriticalSection (&handle_section);
- mono_raise_exception (mono_get_exception_execution_engine ("No weakref support"));
#endif
break;
default:
@@ -429,9 +433,6 @@ ves_icall_System_GCHandle_FreeHandle (guint32 handle)
if (gc_handles [idx] != (gpointer)-1)
GC_unregister_disappearing_link (&(gc_handles [idx]));
}
-#else
- LeaveCriticalSection (&handle_section);
- mono_raise_exception (mono_get_exception_execution_engine ("No GCHandle support"));
#endif
gc_handles [idx] = (gpointer)-1;
@@ -457,11 +458,50 @@ ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle)
if (obj == (MonoObject *) -1)
return NULL;
}
- return obj;
+ if (obj) {
+ MonoClass *klass = mono_object_class (obj);
+ if (klass == mono_defaults.string_class) {
+ return mono_string_chars ((MonoString*)obj);
+ } else if (klass->rank) {
+ return mono_array_addr ((MonoArray*)obj, char, 0);
+ } else {
+ /* the C# code will check and throw the exception */
+ /* FIXME: missing !klass->blittable test, see bug #61134,
+ * disabled in 1.0 untill the blittable-using code is audited.
+ if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ return (gpointer)-1; */
+ return (char*)obj + sizeof (MonoObject);
+ }
+ }
}
return NULL;
}
+guint32
+mono_gchandle_new (MonoObject *obj, gboolean pinned)
+{
+ return ves_icall_System_GCHandle_GetTargetHandle (obj, 0, pinned? HANDLE_PINNED: HANDLE_NORMAL);
+}
+
+guint32
+mono_gchandle_new_weakref (MonoObject *obj, gboolean track_resurrection)
+{
+ return ves_icall_System_GCHandle_GetTargetHandle (obj, 0, track_resurrection? HANDLE_WEAK_TRACK: HANDLE_WEAK);
+}
+
+/* This will return NULL for a collected object if using a weakref handle */
+MonoObject*
+mono_gchandle_get_target (guint32 gchandle)
+{
+ return ves_icall_System_GCHandle_GetTarget (gchandle);
+}
+
+void
+mono_gchandle_free (guint32 gchandle)
+{
+ ves_icall_System_GCHandle_FreeHandle (gchandle);
+}
+
#if HAVE_BOEHM_GC
static HANDLE finalizer_event;
@@ -606,6 +646,12 @@ static GCThreadFunctions mono_gc_thread_vtable = {
};
#endif /* WITH_INCLUDED_LIBGC */
+static void
+mono_gc_warning (char *msg, GC_word arg)
+{
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_GC, msg, (unsigned long)arg);
+}
+
void mono_gc_init (void)
{
InitializeCriticalSection (&handle_section);
@@ -617,6 +663,8 @@ void mono_gc_init (void)
gc_thread_vtable = &mono_gc_thread_vtable;
#endif
+ GC_set_warn_proc (mono_gc_warning);
+
#ifdef ENABLE_FINALIZER_THREAD
if (g_getenv ("GC_DONT_GC")) {
diff --git a/mono/metadata/image.c b/mono/metadata/image.c
index 8b0473429ed..01c9644be34 100644
--- a/mono/metadata/image.c
+++ b/mono/metadata/image.c
@@ -849,12 +849,12 @@ MonoImage *
mono_image_open (const char *fname, MonoImageOpenStatus *status)
{
MonoImage *image, *image2;
- const char *absfname;
+ char *absfname;
g_return_val_if_fail (fname != NULL, NULL);
if (g_path_is_absolute (fname))
- absfname = fname;
+ absfname = (char*)fname;
else {
gchar *path = g_get_current_dir ();
absfname = g_build_filename (path, fname, NULL);
@@ -960,9 +960,22 @@ mono_image_close (MonoImage *image)
if (image->f)
fclose (image->f);
- if (image->raw_data_allocated)
- g_free (image->raw_data);
+ if (image->raw_data_allocated) {
+ /* image->raw_metadata and cli_sections might lie inside image->raw_data */
+ MonoCLIImageInfo *ii = image->image_info;
+ int i;
+
+ if ((image->raw_metadata > image->raw_data) &&
+ (image->raw_metadata <= (image->raw_data + image->raw_data_len)))
+ image->raw_metadata = NULL;
+ for (i = 0; i < ii->cli_section_count; i++)
+ if (((char*)(ii->cli_sections [i]) > image->raw_data) &&
+ ((char*)(ii->cli_sections [i]) <= ((char*)image->raw_data + image->raw_data_len)))
+ ii->cli_sections [i] = NULL;
+
+ g_free (image->raw_data);
+ }
g_free (image->name);
g_free (image->files);
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c
index 81f2af3fa7c..8e278e6feff 100644
--- a/mono/metadata/loader.c
+++ b/mono/metadata/loader.c
@@ -580,28 +580,41 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
g_assert (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL);
- if (exc_class) {
- *exc_class = NULL;
- *exc_arg = NULL;
- }
-
if (method->addr)
return method->addr;
- if (!piinfo->implmap_idx)
- return NULL;
-
- mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
- piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
- import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
- scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
- orig_scope = mono_metadata_string_heap (image, scope_token);
+ if (method->klass->image->dynamic) {
+ MonoReflectionMethodAux *method_aux =
+ mono_g_hash_table_lookup (
+ ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ if (!method_aux)
+ return NULL;
+
+ import = method_aux->dllentry;
+ orig_scope = method_aux->dll;
+ }
+ else {
+ if (!piinfo->implmap_idx)
+ return NULL;
+
+ mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
+
+ piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
+ import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
+ scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
+ orig_scope = mono_metadata_string_heap (image, scope_token);
+ }
mono_dllmap_lookup (image, orig_scope, import, &new_scope, &import);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
"DllImport attempting to load: '%s'.", new_scope);
+ if (exc_class) {
+ *exc_class = NULL;
+ *exc_arg = NULL;
+ }
+
#ifndef PLATFORM_WIN32
/*
* If we are P/Invoking a library from System.Windows.Forms, load Wine
@@ -712,6 +725,21 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
break;
}
+
+#ifdef PLATFORM_WIN32
+ /* Try the stdcall mangled name */
+ if (!method->addr) {
+ /* FIX: Compute this correctly */
+ mangled_name = g_strdup_printf ("%s@%d", import, method->signature->param_count * sizeof (gpointer));
+ g_module_symbol (gmodule, mangled_name, &method->addr);
+ g_free (mangled_name);
+ }
+ if (!method->addr) {
+ mangled_name = g_strdup_printf ("_%s@%d", import, method->signature->param_count * sizeof (gpointer));
+ g_module_symbol (gmodule, mangled_name, &method->addr);
+ g_free (mangled_name);
+ }
+#endif
}
if (!method->addr) {
diff --git a/mono/metadata/locales.c b/mono/metadata/locales.c
index 7c10529f3f3..256598e14c0 100644
--- a/mono/metadata/locales.c
+++ b/mono/metadata/locales.c
@@ -25,7 +25,7 @@
#include <locale.h>
-//#undef DEBUG
+#undef DEBUG
static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2,
gint32 options);
@@ -1041,6 +1041,7 @@ void ves_icall_System_Globalization_CompareInfo_free_internal_collator (MonoComp
coll=this->ICU_collator;
if(coll!=NULL) {
+ this->ICU_collator = NULL;
ucol_close (coll);
}
}
@@ -1431,6 +1432,11 @@ MonoString *ves_icall_System_String_InternalReplace_Str_Comp (MonoString *this,
* does match properly...
*/
match_len = usearch_getMatchedLength (search);
+
+ if(match_len == 0) {
+ continue;
+ }
+
match=(UChar *)g_malloc0 (sizeof(UChar) * (match_len + 1));
usearch_getMatchedText (search, match, match_len, &ec);
@@ -1467,6 +1473,11 @@ MonoString *ves_icall_System_String_InternalReplace_Str_Comp (MonoString *this,
pos!=USEARCH_DONE;
pos=usearch_next (search, &ec)) {
match_len = usearch_getMatchedLength (search);
+
+ if (match_len == 0) {
+ continue;
+ }
+
match=(UChar *)g_malloc0 (sizeof(UChar) * (match_len + 1));
usearch_getMatchedText (search, match, match_len, &ec);
@@ -1865,15 +1876,6 @@ static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2,
/* No options. Kana, symbol and spacing options don't
* apply to the invariant culture.
*/
- if (c1type == G_UNICODE_UPPERCASE_LETTER &&
- c2type == G_UNICODE_LOWERCASE_LETTER) {
- return(1);
- }
-
- if (c1type == G_UNICODE_LOWERCASE_LETTER &&
- c2type == G_UNICODE_UPPERCASE_LETTER) {
- return(-1);
- }
result = (gint32) c1 - c2;
}
diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c
index 2892d81e88b..97a71e3a56a 100644
--- a/mono/metadata/marshal.c
+++ b/mono/metadata/marshal.c
@@ -2198,6 +2198,19 @@ handle_enum:
return res;
}
+static void
+raise_auto_layout_exception (MonoClass *klass)
+{
+ char *msg = g_strdup_printf ("The type `%s.%s' layout needs to be Sequential or Explicit",
+ klass->name_space, klass->name, NULL);
+
+ MonoException *e = mono_exception_from_name_msg (
+ mono_get_corlib (), "System.Runtime.InteropServices",
+ "MarshalDirectiveException", msg);
+ g_free (msg);
+ mono_raise_exception (e);
+}
+
/*
* generates IL code to call managed methods from unmanaged code
*/
@@ -2359,8 +2372,9 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, MonoMars
break;
}
- /* FIXME: Raise a MarshalDirectiveException here */
- g_assert ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT);
+ /* The class can not have an automatic layout */
+ if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ raise_auto_layout_exception (klass);
if (t->attrs & PARAM_ATTRIBUTE_OUT) {
mono_mb_emit_byte (mb, CEE_LDNULL);
@@ -2630,8 +2644,9 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, MonoMars
break;
}
- /* FIXME: Raise a MarshalDirectiveException here */
- g_assert ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT);
+ /* The class can not have an automatic layout */
+ if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ raise_auto_layout_exception (klass);
mono_mb_emit_byte (mb, CEE_STLOC_0);
/* Check for null */
@@ -4845,6 +4860,8 @@ mono_marshal_alloc (gpointer size)
{
MONO_ARCH_SAVE_REGS;
+ if (size == NULL)
+ size = (gpointer)4;
return g_try_malloc ((gulong)size);
}
diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c
index 88699f3e890..3d44463cde9 100644
--- a/mono/metadata/metadata.c
+++ b/mono/metadata/metadata.c
@@ -1203,6 +1203,10 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
{
MonoType *type, *cached;
gboolean byref = FALSE;
+ gboolean pinned = FALSE;
+ const char *tmp_ptr;
+ int count = 0;
+ gboolean found;
/*
* According to the spec, custom modifiers should come before the byref
@@ -1212,70 +1216,70 @@ mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
* Also, this type seems to be different from 'object & modopt(...)'. Maybe
* it would be better to treat byref as real type constructor instead of
* a modifier...
+ * Also, pinned should come before anything else, but some MSV++ produced
+ * assemblies violate this (#bug 61990).
*/
- if (*ptr == MONO_TYPE_BYREF) {
- byref = TRUE;
- ++ptr;
- }
- switch (mode) {
- case MONO_PARSE_MOD_TYPE:
- case MONO_PARSE_PARAM:
- case MONO_PARSE_RET:
- case MONO_PARSE_LOCAL: /* should not have modifiers according to the spec, but ms tools disagree */
- case MONO_PARSE_FIELD: {
- /* count the modifiers */
- const char *tmp_ptr = ptr;
- int count = 0;
- while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
- count++;
- if (count) {
- type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
- type->num_mods = count;
- if (count > 64)
- g_warning ("got more than 64 modifiers in type");
- /* save them this time */
- count = 0;
- while (mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr))
- count++;
+ /* Count the modifiers first */
+ tmp_ptr = ptr;
+ found = TRUE;
+ while (found) {
+ switch (*tmp_ptr) {
+ case MONO_TYPE_PINNED:
+ case MONO_TYPE_BYREF:
+ ++tmp_ptr;
+ break;
+ case MONO_TYPE_CMOD_REQD:
+ case MONO_TYPE_CMOD_OPT:
+ count ++;
+ mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr);
break;
- } /* fall through */
+ default:
+ found = FALSE;
+ }
+ }
+
+ if (count) {
+ type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+ type->num_mods = count;
+ if (count > 64)
+ g_warning ("got more than 64 modifiers in type");
}
- case MONO_PARSE_TYPE:
+ else
/*
* Later we can avoid doing this allocation.
*/
type = g_new0 (MonoType, 1);
- break;
- default:
- g_assert_not_reached ();
+
+ /* Parse pinned, byref and custom modifiers */
+ found = TRUE;
+ count = 0;
+ while (found) {
+ switch (*ptr) {
+ case MONO_TYPE_PINNED:
+ pinned = TRUE;
+ ++ptr;
+ break;
+ case MONO_TYPE_BYREF:
+ byref = TRUE;
+ ++ptr;
+ break;
+ case MONO_TYPE_CMOD_REQD:
+ case MONO_TYPE_CMOD_OPT:
+ count ++;
+ mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr);
+ break;
+ default:
+ found = FALSE;
+ }
}
type->attrs = opt_attrs;
type->byref = byref;
- if (mode == MONO_PARSE_LOCAL) {
- /*
- * check for pinned flag
- */
- if (*ptr == MONO_TYPE_PINNED) {
- type->pinned = 1;
- ++ptr;
- }
- }
+ type->pinned = pinned ? 1 : 0;
+
+ do_mono_metadata_parse_type (type, m, ptr, &ptr);
- switch (*ptr) {
- case MONO_TYPE_BYREF:
- if (mode == MONO_PARSE_FIELD)
- g_warning ("A field type cannot be byref");
- type->byref = 1;
- ptr++;
- /* follow through */
- default:
- /*if (*ptr == MONO_TYPE_VOID && mode != MONO_PARSE_RET)
- g_error ("void not allowed in param");*/
- do_mono_metadata_parse_type (type, m, ptr, &ptr);
- break;
- }
if (rptr)
*rptr = ptr;
diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c
index b8503ecbc4b..b977ec0546d 100644
--- a/mono/metadata/mono-debug.c
+++ b/mono/metadata/mono-debug.c
@@ -45,8 +45,6 @@ extern void (*mono_debugger_class_init_func) (MonoClass *klass);
void
mono_debug_init (MonoDomain *domain, MonoDebugFormat format)
{
- MonoAssembly **ass;
-
g_assert (!mono_debug_initialized);
mono_debug_initialized = TRUE;
@@ -346,25 +344,35 @@ gchar *
mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number,
MonoDomain *domain)
{
- MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
+ char *res;
+ MonoDebugMethodInfo *minfo;
MonoDebugDomainData *domain_data;
- if (!minfo)
+ mono_loader_lock ();
+ minfo = _mono_debug_lookup_method (method);
+ if (!minfo || !minfo->handle || !minfo->handle->symfile ||
+ !minfo->handle->symfile->offset_table) {
+ mono_loader_unlock ();
return NULL;
+ }
domain_data = mono_debug_get_domain_data (minfo->handle, domain);
- if (!domain_data->jit [minfo->index])
+ if (!domain_data->jit [minfo->index]) {
+ mono_loader_unlock ();
return NULL;
+ }
- if (minfo->handle) {
+ if (minfo->handle && minfo->handle->symfile) {
gint32 offset = il_offset_from_address (domain_data->jit [minfo->index], address);
+ char *res = NULL;
- if (offset < 0)
- return NULL;
-
- return mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+ if (offset >= 0)
+ res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+ mono_loader_unlock ();
+ return res;
}
+ mono_loader_unlock ();
return NULL;
}
@@ -381,12 +389,19 @@ mono_debug_source_location_from_address (MonoMethod *method, guint32 address, gu
gchar *
mono_debug_source_location_from_il_offset (MonoMethod *method, guint32 offset, guint32 *line_number)
{
- MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
+ char *res;
+ MonoDebugMethodInfo *minfo;
- if (!minfo || !minfo->handle)
+ mono_loader_lock ();
+ minfo = _mono_debug_lookup_method (method);
+ if (!minfo || !minfo->handle || !minfo->handle->symfile) {
+ mono_loader_unlock ();
return NULL;
+ }
- return mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+ res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+ mono_loader_unlock ();
+ return res;
}
/*
@@ -398,17 +413,24 @@ mono_debug_il_offset_from_address (MonoMethod *method, gint32 address, MonoDomai
{
MonoDebugMethodInfo *minfo;
MonoDebugDomainData *domain_data;
+ gint32 res;
if (address < 0)
return -1;
+ mono_loader_lock ();
minfo = _mono_debug_lookup_method (method);
- if (!minfo || !minfo->il_offsets)
+ if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
+ !minfo->handle->symfile->offset_table) {
+ mono_loader_unlock ();
return -1;
+ }
domain_data = mono_debug_get_domain_data (minfo->handle, domain);
- return il_offset_from_address (domain_data->jit [minfo->index], address);
+ res = il_offset_from_address (domain_data->jit [minfo->index], address);
+ mono_loader_unlock ();
+ return res;
}
/*
@@ -420,17 +442,24 @@ mono_debug_address_from_il_offset (MonoMethod *method, gint32 il_offset, MonoDom
{
MonoDebugMethodInfo *minfo;
MonoDebugDomainData *domain_data;
+ gint32 res;
if (il_offset < 0)
return -1;
+ mono_loader_lock ();
minfo = _mono_debug_lookup_method (method);
- if (!minfo || !minfo->il_offsets)
+ if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
+ !minfo->handle->symfile->offset_table) {
+ mono_loader_unlock ();
return -1;
+ }
domain_data = mono_debug_get_domain_data (minfo->handle, domain);
- return _mono_debug_address_from_il_offset (domain_data->jit [minfo->index], il_offset);
+ res = _mono_debug_address_from_il_offset (domain_data->jit [minfo->index], il_offset);
+ mono_loader_unlock ();
+ return res;
}
MonoDebugDomainData *
@@ -439,6 +468,9 @@ mono_debug_get_domain_data (MonoDebugHandle *handle, MonoDomain *domain)
MonoDebugDomainData *data;
int domain_id = mono_domain_get_id (domain);
+ /* We checked this earlier. */
+ g_assert (handle->symfile);
+
for (data = handle->_priv->domain_table; data; data = data->_priv->next)
if (data->domain_id == domain_id)
return data;
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
index bdf832baa6d..904bd25c868 100644
--- a/mono/metadata/object.c
+++ b/mono/metadata/object.c
@@ -90,6 +90,7 @@ typedef struct
{
guint32 initializing_tid;
guint32 waiting_count;
+ gboolean done;
CRITICAL_SECTION initialization_section;
} TypeInitializationLock;
@@ -177,28 +178,38 @@ mono_runtime_class_init (MonoVTable *vtable)
InitializeCriticalSection (&lock->initialization_section);
lock->initializing_tid = tid;
lock->waiting_count = 1;
+ lock->done = FALSE;
/* grab the vtable lock while this thread still owns type_initialization_section */
EnterCriticalSection (&lock->initialization_section);
g_hash_table_insert (type_initialization_hash, vtable, lock);
do_initialization = 1;
} else {
gpointer blocked;
+ TypeInitializationLock *pending_lock;
- if (lock->initializing_tid == tid) {
+ if (lock->initializing_tid == tid || lock->done) {
LeaveCriticalSection (&type_initialization_section);
return;
}
/* see if the thread doing the initialization is already blocked on this thread */
blocked = GUINT_TO_POINTER (lock->initializing_tid);
- while ((blocked = g_hash_table_lookup (blocked_thread_hash, blocked))) {
- if (blocked == GUINT_TO_POINTER (tid)) {
- LeaveCriticalSection (&type_initialization_section);
- return;
+ while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
+ if (pending_lock->initializing_tid == tid) {
+ if (!pending_lock->done) {
+ LeaveCriticalSection (&type_initialization_section);
+ return;
+ } else {
+ /* the thread doing the initialization is blocked on this thread,
+ but on a lock that has already been freed. It just hasn't got
+ time to awake */
+ break;
+ }
}
+ blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
++lock->waiting_count;
/* record the fact that we are waiting on the initializing thread */
- g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), GUINT_TO_POINTER (lock->initializing_tid));
+ g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
}
LeaveCriticalSection (&type_initialization_section);
@@ -206,6 +217,7 @@ mono_runtime_class_init (MonoVTable *vtable)
mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
if (last_domain)
mono_domain_set (last_domain, TRUE);
+ lock->done = TRUE;
LeaveCriticalSection (&lock->initialization_section);
} else {
/* this just blocks until the initializing thread is done */
@@ -1586,13 +1598,9 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
case MONO_TYPE_R4:
case MONO_TYPE_R8:
case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->byref) {
- /* MS seems to create the objects if a null is passed in */
- if (! ((gpointer *)params->vector)[i])
- ((gpointer*)params->vector)[i] = mono_object_new (mono_domain_get (), mono_class_from_mono_type (sig->params [i]));
- }
- else
- g_assert (((gpointer*)params->vector) [i]);
+ /* MS seems to create the objects if a null is passed in */
+ if (! ((gpointer *)params->vector)[i])
+ ((gpointer*)params->vector)[i] = mono_object_new (mono_domain_get (), mono_class_from_mono_type (sig->params [i]));
pa [i] = (char *)(((gpointer *)params->vector)[i]) + sizeof (MonoObject);
break;
case MONO_TYPE_STRING:
@@ -2715,6 +2723,7 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
MonoDomain *domain;
MonoMethod *method;
MonoMethodSignature *sig;
+ MonoObject *ret;
int i, j, outarg_count = 0;
if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) {
@@ -2739,6 +2748,8 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
*out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
*exc = NULL;
+ ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
+
for (i = 0, j = 0; i < sig->param_count; i++) {
if (sig->params [i]->byref) {
gpointer arg;
@@ -2748,7 +2759,7 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
}
}
- return mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
+ return ret;
}
void
diff --git a/mono/metadata/object.h b/mono/metadata/object.h
index c1ffc3c4c2d..2413cc7a346 100644
--- a/mono/metadata/object.h
+++ b/mono/metadata/object.h
@@ -252,5 +252,11 @@ mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObjec
MonoObject*
mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc);
+/* GC handles support */
+guint32 mono_gchandle_new (MonoObject *obj, gboolean pinned);
+guint32 mono_gchandle_new_weakref (MonoObject *obj, gboolean track_resurrection);
+MonoObject* mono_gchandle_get_target (guint32 gchandle);
+void mono_gchandle_free (guint32 gchandle);
+
#endif
diff --git a/mono/metadata/process.c b/mono/metadata/process.c
index 5e7cce9de7b..5fa57bcf0ed 100644
--- a/mono/metadata/process.c
+++ b/mono/metadata/process.c
@@ -738,7 +738,7 @@ complete_path (const gunichar2 *appname, gunichar2 **completed)
return FALSE;
}
- if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE)) {
+ if (g_file_test (utf8app, G_FILE_TEST_IS_EXECUTABLE) && !g_file_test (utf8app, G_FILE_TEST_IS_DIR)) {
g_free (utf8app);
return FALSE;
}
@@ -875,7 +875,9 @@ MonoBoolean ves_icall_System_Diagnostics_Process_Start_internal (MonoString *app
if(ret) {
process_info->process_handle=procinfo.hProcess;
- process_info->thread_handle=procinfo.hThread;
+ /*process_info->thread_handle=procinfo.hThread;*/
+ process_info->thread_handle=NULL;
+ CloseHandle(procinfo.hThread);
process_info->pid=procinfo.dwProcessId;
process_info->tid=procinfo.dwThreadId;
} else {
diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
index 9640136c0eb..d8335dbdf2f 100644
--- a/mono/metadata/reflection.c
+++ b/mono/metadata/reflection.c
@@ -61,6 +61,9 @@ typedef struct {
MonoMethod *mhandle;
guint32 nrefs;
gpointer *refs;
+ /* for PInvoke */
+ int charset, lasterr, native_cc;
+ MonoString *dll, *dllentry;
} ReflectionMethodBuilder;
const unsigned char table_sizes [64] = {
@@ -1260,6 +1263,14 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb,
rmb->mhandle = mb->mhandle;
rmb->nrefs = 0;
rmb->refs = NULL;
+
+ if (mb->dll) {
+ rmb->charset = rmb->charset & 0xf;
+ rmb->lasterr = rmb->charset & 0x40;
+ rmb->native_cc = rmb->native_cc;
+ rmb->dllentry = mb->dllentry;
+ rmb->dll = mb->dll;
+ }
}
static void
@@ -2716,7 +2727,8 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
* if we have explicitlayout or sequentiallayouts, output data in the
* ClassLayout table.
*/
- if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) && (tb->class_size != -1)) {
+ if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
+ ((tb->class_size > 0) || (tb->packing_size > 0))) {
table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
table->rows++;
alloc_table (table, table->rows);
@@ -5256,12 +5268,21 @@ MonoArray*
mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
{
static MonoClass *System_Reflection_ParameterInfo;
+ static MonoClassField *dbnull_value_field;
+ MonoClass *klass;
MonoArray *res = NULL;
MonoReflectionMethod *member = NULL;
MonoReflectionParameter *param = NULL;
char **names;
int i;
+ if (!dbnull_value_field) {
+ klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
+ mono_class_init (klass);
+ dbnull_value_field = mono_class_get_field_from_name (klass, "Value");
+ g_assert (dbnull_value_field);
+ }
+
if (!System_Reflection_ParameterInfo)
System_Reflection_ParameterInfo = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "ParameterInfo");
@@ -5283,7 +5304,7 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
param = (MonoReflectionParameter *)mono_object_new (domain,
System_Reflection_ParameterInfo);
param->ClassImpl = mono_type_get_object (domain, method->signature->params [i]);
- param->DefaultValueImpl = NULL; /* FIXME */
+ param->DefaultValueImpl = mono_field_get_value_object (domain, dbnull_value_field, NULL); /* FIXME */
param->MemberImpl = (MonoObject*)member;
param->NameImpl = mono_string_new (domain, names [i]);
param->PositionImpl = i;
@@ -5868,6 +5889,7 @@ handle_type:
}
break;
case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
for (i = 0; i < alen; i++) {
MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
@@ -7005,6 +7027,17 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
} else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
/* TODO */
m->signature->pinvoke = 1;
+
+ method_aux = g_new0 (MonoReflectionMethodAux, 1);
+
+ method_aux->dllentry = g_strdup (mono_string_to_utf8 (rmb->dllentry));
+ method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll));
+
+ ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 1) | rmb->lasterr;
+
+ if (klass->image->dynamic)
+ mono_g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+
return m;
} else if (!m->klass->dummy &&
!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
@@ -7818,6 +7851,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
{
MonoClass *klass;
MonoReflectionType* res;
+ int i;
MONO_ARCH_SAVE_REGS;
@@ -7828,7 +7862,6 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
/*
* Fields to set in klass:
* the various flags: delegate/unicode/contextbound etc.
- * nested_classes
*/
klass->flags = tb->attrs;
@@ -7840,6 +7873,13 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
if (!klass->enumtype)
ensure_runtime_vtable (klass);
+ if (tb->subtypes) {
+ for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
+ MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
+ klass->nested_classes = g_list_prepend (klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type));
+ }
+ }
+
/* fields and object layout */
if (klass->parent) {
if (!klass->parent->size_inited)
diff --git a/mono/metadata/reflection.h b/mono/metadata/reflection.h
index e44243f3d66..f365047c3b6 100644
--- a/mono/metadata/reflection.h
+++ b/mono/metadata/reflection.h
@@ -34,6 +34,7 @@ typedef struct {
char **param_names;
MonoMarshalSpec **param_marshall;
MonoCustomAttrInfo **param_cattr;
+ char *dllentry, *dll;
} MonoReflectionMethodAux;
int mono_reflection_parse_type (char *name, MonoTypeNameParse *info);
diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c
index c2b129984e7..1ef49278ea9 100644
--- a/mono/metadata/socket-io.c
+++ b/mono/metadata/socket-io.c
@@ -330,6 +330,11 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level,
case SocketOptionName_Type:
*system_name = SO_TYPE;
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ *system_name = SO_PEERCRED;
+ break;
+#endif
case SocketOptionName_ExclusiveAddressUse:
case SocketOptionName_UseLoopback:
case SocketOptionName_MaxConnections:
@@ -1155,7 +1160,15 @@ gint32 ves_icall_System_Net_Sockets_Socket_RecvFrom_internal(SOCKET sock, MonoAr
return(0);
}
- *sockaddr=create_object_from_sockaddr(sa, sa_size, error);
+ /* If we didn't get a socket size, then we're probably a
+ * connected connection-oriented socket and the stack hasn't
+ * returned the remote address. All we can do is return null.
+ */
+ if ( sa_size != 0 )
+ *sockaddr=create_object_from_sockaddr(sa, sa_size, error);
+ else
+ *sockaddr=NULL;
+
g_free(sa);
return(ret);
@@ -1428,6 +1441,10 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc
int lingersize=sizeof(linger);
struct timeval tv;
int tvsize=sizeof(tv);
+#ifdef SO_PEERCRED
+ struct ucred cred;
+ int credsize = sizeof(cred);
+#endif
MonoDomain *domain=mono_domain_get();
MonoObject *obj;
MonoClass *obj_class;
@@ -1461,6 +1478,13 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc
&tvsize);
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ ret = _wapi_getsockopt (sock, system_level, system_name, &cred,
+ &credsize);
+ break;
+#endif
+
default:
ret = _wapi_getsockopt (sock, system_level, system_name, &val,
&valsize);
@@ -1500,6 +1524,32 @@ void ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal(SOCKET soc
obj = int_to_object (domain, (tv.tv_sec * 1000) + (tv.tv_usec / 1000));
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ {
+ /* build a Mono.Posix.PeerCred+PeerCredData if
+ * possible
+ */
+ MonoImage *mono_posix_image = mono_image_loaded ("Mono.Posix");
+ MonoPeerCredData *cred_data;
+
+ if (mono_posix_image == NULL) {
+ *error = WSAENOPROTOOPT;
+ return;
+ }
+
+ obj_class = mono_class_from_name(mono_posix_image,
+ "Mono.Posix",
+ "PeerCred/PeerCredData");
+ obj = mono_object_new(domain, obj_class);
+ cred_data = (MonoPeerCredData *)obj;
+ cred_data->pid = cred.pid;
+ cred_data->uid = cred.uid;
+ cred_data->gid = cred.gid;
+ break;
+ }
+#endif
+
default:
obj = int_to_object (domain, val);
}
diff --git a/mono/metadata/socket-io.h b/mono/metadata/socket-io.h
index 3540882f105..5c2ee72181a 100644
--- a/mono/metadata/socket-io.h
+++ b/mono/metadata/socket-io.h
@@ -130,7 +130,12 @@ typedef enum {
SocketOptionName_BsdUrgent=2,
SocketOptionName_Expedited=2,
SocketOptionName_NoChecksum=1,
- SocketOptionName_ChecksumCoverage=20
+ SocketOptionName_ChecksumCoverage=20,
+
+ /* This is Mono-specific, keep it in sync with
+ * Mono.Posix/PeerCred.cs
+ */
+ SocketOptionName_PeerCred=10001
} MonoSocketOptionName;
typedef struct _MonoSocketAsyncResult {
@@ -154,6 +159,14 @@ typedef struct _MonoSocketAsyncResult {
gint error;
} MonoSocketAsyncResult;
+typedef struct
+{
+ MonoObject obj;
+ gint pid;
+ gint uid;
+ gint gid;
+} MonoPeerCredData;
+
extern gpointer ves_icall_System_Net_Sockets_Socket_Socket_internal(MonoObject *this, gint32 family, gint32 type, gint32 proto, gint32 *error);
extern void ves_icall_System_Net_Sockets_Socket_Close_internal(SOCKET sock, gint32 *error);
extern gint32 ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal(void);
diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog
index cdcd480a069..8e09b509dbc 100644
--- a/mono/mini/ChangeLog
+++ b/mono/mini/ChangeLog
@@ -1,3 +1,68 @@
+2004-09-17 Zoltan Varga <vargaz@freemail.hu>
+
+ * mini.c (mono_method_to_ir): Fix LDSTR in dynamic methods. Fixes #66132.
+
+2004-09-11 Ben Maurer <bmaurer@users.sourceforge.net>
+
+ * inssel.brg: make ldelema check aot friendly.
+
+Thu Sep 9 20:57:53 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * mini-*.c, mini-ops.h, inssel-long32.brg: introduced
+ OP_ADDCC_IMM and OP_SUBCC_IMM (add/sub immediate that will
+ set the carry/borrow flag). The sparc and s390 implementations
+ can now use optimized versions (and simplify the code). ppc bugfixes.
+
+2004-09-02 Zoltan Varga <vargaz@freemail.hu>
+
+ * inssel-long32.brg: Fix OP_LCONV_TO_OVF_I1 rule. Fixes #64578.
+
+2004-08-23 Zoltan Varga <vargaz@freemail.hu>
+
+ * inssel-x86.brg inssel-amd64: Add yet another missing tree->dreg assignment.
+
+ * mini-x86.c (mono_arch_local_regalloc): Fix bug in long register
+ allocation. Fixes #63085.
+
+2004-08-09 Zoltan Varga <vargaz@freemail.hu>
+
+ * inssel-x86.brg: Set dreg of LOCALLOC correctly.
+
+Tue Aug 3 11:20:09 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * mini-ppc.c: mul.ovf.un exception name fix.
+
+Tue Aug 3 11:19:07 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * mini-ppc.c: reg allocator fix.
+
+Tue Aug 3 11:17:07 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * mini-ppc.c: make sure temp regs are not used for global reg
+ allocation.
+
+Tue Jul 27 16:05:19 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * mini-ppc.c, mini-sparc.c, mini-s390.c: keep track of line
+ numbers in the debug info (spotted by Geoff Norton,
+ <gnorton@customerdna.com>).
+
+Mon Jul 12 17:47:00 CEST 2004 Paolo Molaro <lupus@ximian.com>
+
+ * inssel-ppc.brg: arguments on the stack are always
+ relative to the stack pointer (spotted by Neale Ferguson).
+
+2004-07-11 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * exceptions-x86.c: delay appending the method name to the trace until
+ after mono_jit_info_table_find is called, as this gets the real
+ MonoMethod.
+
+2004-07-08 Zoltan Varga <vargaz@freemail.hu>
+
+ * mini.c (handle_stack_args): Handle some corner cases. Fixes
+ 58863.
+
2004-07-05 Zoltan Varga <vargaz@freemail.hu>
* mini.c (optimize_branches): Fix linking of bblocks in branch->branch
diff --git a/mono/mini/basic-long.cs b/mono/mini/basic-long.cs
index f16f9f5dcb1..4b321017ce7 100644
--- a/mono/mini/basic-long.cs
+++ b/mono/mini/basic-long.cs
@@ -263,6 +263,12 @@ class Tests {
return 1;
}
+ static int test_4_addcc_imm () {
+ long a = 3;
+ long b = 0;
+ return (int)(a - b + 1);
+ }
+
static int test_5_sub () {
long a = 8;
long b = 3;
diff --git a/mono/mini/cpu-g4.md b/mono/mini/cpu-g4.md
index 7d76db87792..638fb2828bc 100644
--- a/mono/mini/cpu-g4.md
+++ b/mono/mini/cpu-g4.md
@@ -545,6 +545,8 @@ adc: dest:i src1:i src2:i len:4
addcc: dest:i src1:i src2:i len:4
subcc: dest:i src1:i src2:i len:4
adc_imm: dest:i src1:i len:12
+addcc_imm: dest:i src1:i len:12
+subcc_imm: dest:i src1:i len:12
sbb: dest:i src1:i src2:i len:4
sbb_imm: dest:i src1:i len:12
br_reg: src1:i len:8
diff --git a/mono/mini/cpu-pentium.md b/mono/mini/cpu-pentium.md
index 2568eac81f6..e48ba96540e 100644
--- a/mono/mini/cpu-pentium.md
+++ b/mono/mini/cpu-pentium.md
@@ -354,7 +354,9 @@ loadr8_membase: dest:f src1:b len:6
loadr8_spill_membase: src1:b len:8
loadu4_mem: dest:i len:9
move: dest:i src1:i len:2
+addcc_imm: dest:i src1:i len:6 clob:1
add_imm: dest:i src1:i len:6 clob:1
+subcc_imm: dest:i src1:i len:6 clob:1
sub_imm: dest:i src1:i len:6 clob:1
mul_imm: dest:i src1:i len:6
# there is no actual support for division or reminder by immediate
diff --git a/mono/mini/cpu-s390.md b/mono/mini/cpu-s390.md
index 256bf4aa609..3cc63d770d1 100644
--- a/mono/mini/cpu-s390.md
+++ b/mono/mini/cpu-s390.md
@@ -349,7 +349,9 @@ loadu4_mem: dest:i len:8
move: dest:i src1:i len:4
fmove: dest:f src1:f len:4
add_imm: dest:i src1:i len:18
+addcc_imm: dest:i src1:i len:18
sub_imm: dest:i src1:i len:18
+subcc_imm: dest:i src1:i len:18
mul_imm: dest:i src1:i len:18
# there is no actual support for division or reminder by immediate
# we simulate them, though (but we need to change the burg rules
diff --git a/mono/mini/cpu-sparc.md b/mono/mini/cpu-sparc.md
index 8f9280a222b..6fef70d713d 100644
--- a/mono/mini/cpu-sparc.md
+++ b/mono/mini/cpu-sparc.md
@@ -356,7 +356,9 @@ loadr8_membase: dest:f src1:b len:20
loadu4_mem: dest:i len:8
move: dest:i src1:i len:4
add_imm: dest:i src1:i len:12
+addcc_imm: dest:i src1:i len:64
sub_imm: dest:i src1:i len:12
+subcc_imm: dest:i src1:i len:64
mul_imm: dest:i src1:i len:12
div_imm: dest:a src1:i src2:i len:28
div_un_imm: dest:a src1:i src2:i len:12
diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c
index b0783ae39b1..c0961c485d2 100644
--- a/mono/mini/exceptions-x86.c
+++ b/mono/mini/exceptions-x86.c
@@ -462,9 +462,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
if (!(*lmf)->method)
return (gpointer)-1;
- if (trace)
- *trace = g_strdup_printf ("in (unmanaged) %s", mono_method_full_name ((*lmf)->method, TRUE));
-
if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
*res = *ji;
} else {
@@ -472,6 +469,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
res->method = (*lmf)->method;
}
+ if (trace)
+ *trace = g_strdup_printf ("in (unmanaged) %s", mono_method_full_name (res->method, TRUE));
+
new_ctx->SC_ESI = (*lmf)->esi;
new_ctx->SC_EDI = (*lmf)->edi;
new_ctx->SC_EBX = (*lmf)->ebx;
diff --git a/mono/mini/inssel-long32.brg b/mono/mini/inssel-long32.brg
index 0d1cf077f2d..2ebeb3c27b7 100644
--- a/mono/mini/inssel-long32.brg
+++ b/mono/mini/inssel-long32.brg
@@ -108,7 +108,7 @@ lreg: OP_LADD_OVF_UN (lreg, lreg) {
}
lreg: OP_LADD (lreg, i8con) {
- MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_ADDCC_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
}
@@ -118,7 +118,7 @@ lreg: OP_LSUB (lreg, lreg) {
}
lreg: OP_LSUB (lreg, i8con) {
- MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_SUBCC_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
}
@@ -575,15 +575,30 @@ reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
}
reg: OP_LCONV_TO_OVF_I1 (lreg) {
+ MonoInst *is_negative, *end_label;
+
+ MONO_NEW_LABEL (s, is_negative);
+ MONO_NEW_LABEL (s, end_label);
+
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
+
+ /* Positive */
MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
- MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
+
+ /* Negative */
+ mono_bblock_add_inst (s->cbb, is_negative);
MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
- MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (s, LT_UN, "OverflowException");
+ mono_bblock_add_inst (s->cbb, end_label);
+
MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
}
diff --git a/mono/mini/inssel-ppc.brg b/mono/mini/inssel-ppc.brg
index a4043e1d797..38eced8c0dc 100644
--- a/mono/mini/inssel-ppc.brg
+++ b/mono/mini/inssel-ppc.brg
@@ -131,7 +131,7 @@ stmt: OP_SETRET (OP_ICONST) {
stmt: OP_OUTARG (reg) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->reg1);
return;
}
tree->opcode = OP_SETREG;
@@ -142,7 +142,7 @@ stmt: OP_OUTARG (reg) {
stmt: OP_OUTARG (OP_REGVAR) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->tree->dreg);
return;
}
tree->opcode = OP_SETREG;
@@ -153,8 +153,8 @@ stmt: OP_OUTARG (OP_REGVAR) {
stmt: OP_OUTARG (lreg) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2);
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->reg2);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, tree->inst_imm + 4, state->left->reg1);
return;
}
MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
@@ -166,7 +166,7 @@ stmt: OP_OUTARG (lreg) {
stmt: OP_OUTARG (OP_ICONST) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0);
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, ppc_r1, tree->inst_imm, state->left->tree->inst_c0);
return;
}
tree->opcode = OP_SETREGIMM;
@@ -205,7 +205,7 @@ stmt: OP_OUTARG (OP_ICONST) {
stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->left->tree->dreg);
return;
}
tree->opcode = OP_SETREG;
@@ -223,7 +223,7 @@ stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
stmt: OP_OUTARG (freg) {
if (tree->inst_imm) {
int opcode = (tree->unused & 0xff00) == 0x0400? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG;
- MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, s->frame_reg, tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, ppc_r1, tree->inst_imm, state->left->reg1);
return;
}
tree->opcode = OP_SETFREG;
@@ -234,7 +234,7 @@ stmt: OP_OUTARG (freg) {
stmt: OP_OUTARG_R4 (freg) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->reg1);
return;
}
tree->opcode = OP_SETFREG;
@@ -245,7 +245,7 @@ stmt: OP_OUTARG_R4 (freg) {
stmt: OP_OUTARG_R8 (freg) {
if (tree->inst_imm) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, ppc_r1, tree->inst_imm, state->left->reg1);
return;
}
tree->opcode = OP_SETFREG;
@@ -269,7 +269,7 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
}
//g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset);
if (ovf_size != 0) {
- mini_emit_memcpy (s, s->frame_reg, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
+ mini_emit_memcpy (s, ppc_r1, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
}
}
diff --git a/mono/mini/inssel-x86.brg b/mono/mini/inssel-x86.brg
index b1f1cf67c77..b80affe25ab 100644
--- a/mono/mini/inssel-x86.brg
+++ b/mono/mini/inssel-x86.brg
@@ -151,6 +151,7 @@ reg: OP_LOCALLOC (OP_ICONST) {
if (tree->flags & MONO_INST_INIT) {
/* microcoded in mini-x86.c */
tree->sreg1 = mono_regstate_next_int (s->rs);
+ tree->dreg = state->reg1;
MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
mono_bblock_add_inst (s->cbb, tree);
} else {
@@ -161,6 +162,7 @@ reg: OP_LOCALLOC (OP_ICONST) {
reg: OP_LOCALLOC (reg) {
tree->sreg1 = state->left->tree->dreg;
+ tree->dreg = state->reg1;
mono_bblock_add_inst (s->cbb, tree);
}
diff --git a/mono/mini/inssel.brg b/mono/mini/inssel.brg
index e0bc1f0254b..0cb8129cca0 100644
--- a/mono/mini/inssel.brg
+++ b/mono/mini/inssel.brg
@@ -1736,7 +1736,14 @@ reg: OP_CHECK_ARRAY_TYPE (reg) {
vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass));
MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, elclass_reg,
class_reg, G_STRUCT_OFFSET (MonoClass, element_class));
- MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, elclass_reg, tree->klass);
+ if (mono_compile_aot) {
+ int klass_reg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_NEW_CLASSCONST (s, klass_reg, tree->klass);
+ MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, elclass_reg, klass_reg);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, elclass_reg, tree->klass);
+ }
+
MONO_EMIT_NEW_COND_EXC (s, NE_UN, "ArrayTypeMismatchException");
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
}
diff --git a/mono/mini/mini-ops.h b/mono/mini/mini-ops.h
index 32b6eb5f35e..98da133d3fa 100644
--- a/mono/mini/mini-ops.h
+++ b/mono/mini/mini-ops.h
@@ -297,7 +297,9 @@ MINI_OP(OP_ADC_IMM, "adc_imm")
MINI_OP(OP_SBB, "sbb")
MINI_OP(OP_SBB_IMM, "sbb_imm")
MINI_OP(OP_ADDCC, "addcc")
+MINI_OP(OP_ADDCC_IMM, "addcc_imm")
MINI_OP(OP_SUBCC, "subcc")
+MINI_OP(OP_SUBCC_IMM, "subcc_imm")
MINI_OP(OP_BR_REG, "br_reg")
MINI_OP(OP_SEXT_I1, "sext_i1")
MINI_OP(OP_SEXT_I2, "sext_i2")
diff --git a/mono/mini/mini-ppc.c b/mono/mini/mini-ppc.c
index a62d49bd453..92bef163894 100644
--- a/mono/mini/mini-ppc.c
+++ b/mono/mini/mini-ppc.c
@@ -209,7 +209,7 @@ mono_arch_get_global_int_regs (MonoCompile *cfg)
if (cfg->frame_reg != ppc_sp)
top = 31;
#if USE_EXTRA_TEMPS
- top -= 2;
+ top = 29;
#endif
for (i = 13; i < top; ++i)
regs = g_list_prepend (regs, GUINT_TO_POINTER (i));
@@ -1296,7 +1296,11 @@ mono_spillvar_offset_float (MonoCompile *cfg, int spillvar)
#undef DEBUG
#define DEBUG(a) if (cfg->verbose_level > 1) a
//#define DEBUG(a)
-#define reg_is_freeable(r) ((r) >= 3 && (r) <= 10)
+/* use ppc_r3-ppc_10,ppc_r12 as temp registers, f1-f13 for FP registers */
+#define PPC_CALLER_REGS ((0xff<<3) | (1<<12) | USE_EXTRA_TEMPS)
+#define PPC_CALLER_FREGS (0x3ffe)
+
+#define reg_is_freeable(r) (PPC_CALLER_REGS & 1 << (r))
#define freg_is_freeable(r) ((r) >= 1 && (r) <= 13)
typedef struct {
@@ -1631,10 +1635,6 @@ alloc_int_reg (MonoCompile *cfg, InstList *curinst, MonoInst *ins, int sym_reg,
return val;
}
-/* use ppc_r3-ppc_10,ppc_r12 as temp registers, f1-f13 for FP registers */
-#define PPC_CALLER_REGS ((0xff<<3) | (1<<12) | USE_EXTRA_TEMPS)
-#define PPC_CALLER_FREGS (0x3ffe)
-
/*
* Local register allocation.
* We first scan the list of instructions and we save the liveness info of
@@ -2275,6 +2275,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
}
// if (ins->cil_code)
// g_print ("cil code\n");
+ mono_debug_record_line_number (cfg, ins, offset);
switch (ins->opcode) {
case OP_BIGMUL:
@@ -2442,6 +2443,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case OP_ADC:
ppc_adde (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
+ case OP_ADDCC_IMM:
+ if (ppc_is_imm16 (ins->inst_imm)) {
+ ppc_addic (code, ins->dreg, ins->sreg1, ins->inst_imm);
+ } else {
+ ppc_load (code, ppc_r11, ins->inst_imm);
+ ppc_addc (code, ins->dreg, ins->sreg1, ppc_r11);
+ }
+ break;
case OP_ADD_IMM:
if (ppc_is_imm16 (ins->inst_imm)) {
ppc_addi (code, ins->dreg, ins->sreg1, ins->inst_imm);
@@ -2521,6 +2530,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case OP_SUBCC:
ppc_subfc (code, ins->dreg, ins->sreg2, ins->sreg1);
break;
+ case OP_SUBCC_IMM:
+ ppc_load (code, ppc_r11, ins->inst_imm);
+ ppc_subfc (code, ins->dreg, ppc_r11, ins->sreg1);
+ break;
case CEE_SUB:
ppc_subf (code, ins->dreg, ins->sreg2, ins->sreg1);
break;
@@ -2538,7 +2551,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
break;
case OP_SBB_IMM:
ppc_load (code, ppc_r11, ins->inst_imm);
- ppc_subfe (code, ins->dreg, ins->sreg2, ppc_r11);
+ ppc_subfe (code, ins->dreg, ppc_r11, ins->sreg1);
break;
case OP_PPC_SUBFIC:
g_assert (ppc_is_imm16 (ins->inst_imm));
@@ -2686,7 +2699,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
*/
ppc_mulhwu (code, ppc_r0, ins->sreg1, ins->sreg2);
ppc_cmpi (code, 0, 0, ppc_r0, 0);
- EMIT_COND_SYSTEM_EXCEPTION (CEE_BNE_UN - CEE_BEQ, ins->inst_p1);
+ EMIT_COND_SYSTEM_EXCEPTION (CEE_BNE_UN - CEE_BEQ, "OverflowException");
ppc_mullw (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_ICONST:
@@ -3409,6 +3422,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
ArgInfo *ainfo = cinfo->args + i;
inst = cfg->varinfo [pos];
+ if (cfg->verbose_level > 2)
+ g_print ("Saving argument %d (type: %d)\n", i, ainfo->regtype);
if (inst->opcode == OP_REGVAR) {
if (ainfo->regtype == RegTypeGeneral)
ppc_mr (code, inst->dreg, ainfo->reg);
diff --git a/mono/mini/mini-s390.c b/mono/mini/mini-s390.c
index 101c5c7ec76..6d7f7ce718b 100644
--- a/mono/mini/mini-s390.c
+++ b/mono/mini/mini-s390.c
@@ -2944,6 +2944,8 @@ guint8 cond;
code = cfg->native_code + offset;
}
+ mono_debug_record_line_number (cfg, ins, offset);
+
switch (ins->opcode) {
case OP_STOREI1_MEMBASE_IMM: {
s390_lhi (code, s390_r14, ins->inst_imm);
@@ -3226,6 +3228,7 @@ guint8 cond;
s390_alcr (code, ins->dreg, ins->sreg2);
}
break;
+ case OP_ADDCC_IMM:
case OP_ADD_IMM: {
if ((ins->next) &&
(ins->next->opcode == OP_ADC_IMM)) {
@@ -3291,6 +3294,7 @@ guint8 cond;
s390_slbr (code, ins->dreg, ins->sreg2);
}
break;
+ case OP_SUBCC_IMM:
case OP_SUB_IMM: {
if (s390_is_imm16 (-ins->inst_imm)) {
if (ins->dreg != ins->sreg1) {
diff --git a/mono/mini/mini-sparc.c b/mono/mini/mini-sparc.c
index 54fd7fda138..1552e50c16e 100644
--- a/mono/mini/mini-sparc.c
+++ b/mono/mini/mini-sparc.c
@@ -2546,6 +2546,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
code_start = (guint8*)code;
// if (ins->cil_code)
// g_print ("cil code\n");
+ mono_debug_record_line_number (cfg, ins, offset);
switch (ins->opcode) {
case OP_STOREI1_MEMBASE_IMM:
@@ -2651,6 +2652,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case CEE_ADD:
sparc_add (code, FALSE, ins->sreg1, ins->sreg2, ins->dreg);
break;
+ case OP_ADDCC_IMM:
case OP_ADD_IMM:
/* according to inssel-long32.brg, this should set cc */
EMIT_ALU_IMM (ins, add, TRUE);
@@ -2668,6 +2670,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case CEE_SUB:
sparc_sub (code, FALSE, ins->sreg1, ins->sreg2, ins->dreg);
break;
+ case OP_SUBCC_IMM:
case OP_SUB_IMM:
/* according to inssel-long32.brg, this should set cc */
EMIT_ALU_IMM (ins, sub, TRUE);
diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c
index 14710b31792..dc098a1c26b 100644
--- a/mono/mini/mini-x86.c
+++ b/mono/mini/mini-x86.c
@@ -1866,6 +1866,8 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
/* force source to be same as dest */
rs->iassign [ins->sreg1] = ins->dreg;
rs->iassign [ins->sreg1 + 1] = ins->unused;
+ rs->isymbolic [ins->dreg] = ins->sreg1;
+ rs->isymbolic [ins->unused] = ins->sreg1 + 1;
DEBUG (g_print ("\tassigned sreg1 (long) %s to sreg1 R%d\n", mono_arch_regname (ins->dreg), ins->sreg1));
DEBUG (g_print ("\tassigned sreg1 (long-high) %s to sreg1 R%d\n", mono_arch_regname (ins->unused), ins->sreg1 + 1));
@@ -2324,6 +2326,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case OP_ADC:
x86_alu_reg_reg (code, X86_ADC, ins->sreg1, ins->sreg2);
break;
+ case OP_ADDCC_IMM:
case OP_ADD_IMM:
x86_alu_reg_imm (code, X86_ADD, ins->dreg, ins->inst_imm);
break;
@@ -2337,6 +2340,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
case OP_SBB:
x86_alu_reg_reg (code, X86_SBB, ins->sreg1, ins->sreg2);
break;
+ case OP_SUBCC_IMM:
case OP_SUB_IMM:
x86_alu_reg_imm (code, X86_SUB, ins->dreg, ins->inst_imm);
break;
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index d1e340a5966..28f70d463c3 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -1581,23 +1581,24 @@ mono_compile_get_interface_var (MonoCompile *cfg, int slot, MonoInst *ins)
*/
static int
handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int count) {
- int i;
+ int i, bindex;
MonoBasicBlock *outb;
MonoInst *inst, **locals;
+ gboolean found;
if (!count)
return 0;
if (cfg->verbose_level > 3)
g_print ("%d item(s) on exit from B%d\n", count, bb->block_num);
if (!bb->out_scount) {
- int found = 0;
bb->out_scount = count;
//g_print ("bblock %d has out:", bb->block_num);
+ found = FALSE;
for (i = 0; i < bb->out_count; ++i) {
outb = bb->out_bb [i];
//g_print (" %d", outb->block_num);
if (outb->in_stack) {
- found = 1;
+ found = TRUE;
bb->out_stack = outb->in_stack;
break;
}
@@ -1606,19 +1607,34 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
if (!found) {
bb->out_stack = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * count);
for (i = 0; i < count; ++i) {
-/* see bug#58863, but removing this code causes regressions in gtk-sharp build
- * (SEGV running Method::Initialize() in gapi_codegen.exe)
- */
-#if 1
- /* try to reuse temps already allocated for this purpouse, if they occupy the same
- * stack slot and if they are of the same type. */
- bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
-#else
- bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
-#endif
+ /*
+ * try to reuse temps already allocated for this purpouse, if they occupy the same
+ * stack slot and if they are of the same type.
+ * This won't cause conflicts since if 'local' is used to
+ * store one of the values in the in_stack of a bblock, then
+ * the same variable will be used for the same outgoing stack
+ * slot as well.
+ * This doesn't work when inlining methods, since the bblocks
+ * in the inlined methods do not inherit their in_stack from
+ * the bblock they are inlined to. See bug #58863 for an
+ * example.
+ */
+ if (cfg->inlined_method)
+ bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
+ else
+ bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
}
}
}
+
+ for (i = 0; i < bb->out_count; ++i) {
+ outb = bb->out_bb [i];
+ if (outb->in_scount)
+ continue; /* check they are the same locals */
+ outb->in_scount = count;
+ outb->in_stack = bb->out_stack;
+ }
+
locals = bb->out_stack;
for (i = 0; i < count; ++i) {
/* add store ops at the end of the bb, before the branch */
@@ -1633,14 +1649,36 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun
if (cfg->verbose_level > 3)
g_print ("storing %d to temp %d\n", i, locals [i]->inst_c0);
}
-
- for (i = 0; i < bb->out_count; ++i) {
- outb = bb->out_bb [i];
- if (outb->in_scount)
- continue; /* check they are the same locals */
- outb->in_scount = count;
- outb->in_stack = locals;
+
+ /*
+ * It is possible that the out bblocks already have in_stack assigned, and
+ * the in_stacks differ. In this case, we will store to all the different
+ * in_stacks.
+ */
+
+ found = TRUE;
+ bindex = 0;
+ while (found) {
+ /* Find a bblock which has a different in_stack */
+ found = FALSE;
+ while (bindex < bb->out_count) {
+ outb = bb->out_bb [bindex];
+ if (outb->in_stack != locals) {
+ /*
+ * Instead of storing sp [i] to locals [i], we need to store
+ * locals [i] to <new locals>[i], since the sp [i] tree can't
+ * be shared between trees.
+ */
+ for (i = 0; i < count; ++i)
+ mono_add_varcopy_to_end (cfg, bb, locals [i]->inst_c0, outb->in_stack [i]->inst_c0);
+ locals = outb->in_stack;
+ found = TRUE;
+ break;
+ }
+ bindex ++;
+ }
}
+
return 0;
}
@@ -2427,6 +2465,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
MonoMethodHeader *cheader;
MonoBasicBlock *ebblock, *sbblock;
int i, costs, new_locals_offset;
+ MonoMethod *prev_inlined_method;
if (cfg->verbose_level > 2)
g_print ("INLINE START %p %s -> %s\n", cmethod, mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
@@ -2455,8 +2494,13 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
ebblock->block_num = cfg->num_bblocks++;
ebblock->real_offset = real_offset;
+ prev_inlined_method = cfg->inlined_method;
+ cfg->inlined_method = cmethod;
+
costs = mono_method_to_ir (cfg, cmethod, sbblock, ebblock, new_locals_offset, rvar, dont_inline, sp, real_offset, *ip == CEE_CALLVIRT);
+ cfg->inlined_method = prev_inlined_method;
+
if ((costs >= 0 && costs < 60) || inline_allways) {
if (cfg->verbose_level > 2)
g_print ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
@@ -3849,7 +3893,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
CHECK_OPSIZE (5);
n = read32 (ip + 1);
- if (method->wrapper_type != MONO_WRAPPER_NONE) {
+ if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) {
+ NEW_PCONST (cfg, ins, mono_method_get_wrapper_data (method, n));
+ ins->cil_code = ip;
+ ins->type = STACK_OBJ;
+ *sp = ins;
+ }
+ else if (method->wrapper_type != MONO_WRAPPER_NONE) {
int temp;
MonoInst *iargs [1];
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index adc1e9086b5..e62be1b95cb 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -492,6 +492,7 @@ typedef struct {
MonoSpillInfo *spill_info_float; /* fp register spills */
gint spill_count;
/* unsigned char *cil_code; */
+ MonoMethod *inlined_method; /* the method which is currently inlined */
/* the exception object passed to catch/filter blocks */
MonoInst *exvar;
diff --git a/mono/tests/ChangeLog b/mono/tests/ChangeLog
index e73b632c1c1..041938869bd 100644
--- a/mono/tests/ChangeLog
+++ b/mono/tests/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-07 Duncan Mak <duncan@ximian.com>
+
+ * typeof-ptr.cs: Add unsafe sections to the code that's using
+ pointers directly. This was breaking the test stage on the build
+ boxes.
+
2004-05-29 Zoltan Varga <vargaz@freemail.hu>
* invoke.cs: Add an Invoke test.
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
index 23cc36cc3cc..2ac008e74c4 100644
--- a/mono/tests/Makefile.am
+++ b/mono/tests/Makefile.am
@@ -41,6 +41,7 @@ TEST_CS_SRC= \
exception16.cs \
struct.cs \
valuetype-gettype.cs \
+ typeof-ptr.cs \
static-constructor.cs \
pinvoke.cs \
pinvoke1.cs \
diff --git a/mono/tests/typeof-ptr.cs b/mono/tests/typeof-ptr.cs
new file mode 100644
index 00000000000..69e75ca1745
--- /dev/null
+++ b/mono/tests/typeof-ptr.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Reflection;
+
+class T {
+ public static unsafe void meth (int a, int* b) {
+ }
+ static int Main () {
+ ParameterInfo[] args = typeof (T).GetMethod ("meth").GetParameters ();
+ if (args[0].ParameterType == args[1].ParameterType)
+ return 1;
+
+ unsafe {
+ if (typeof(int) == typeof (int*))
+ return 2;
+ }
+ if (args[0].ParameterType != typeof(int))
+ return 3;
+
+ unsafe {
+ if (args[1].ParameterType != typeof(int*))
+ return 4;
+ }
+
+ return 0;
+ }
+}
diff --git a/web/download b/web/download
index 6a9789d3744..3992312f61f 100644
--- a/web/download
+++ b/web/download
@@ -14,21 +14,123 @@
Online API documentation for Mono is available in the `monodoc' package.
- Gtk-sharp is package to build GUI applications with the Gtk toolkit.
-
+ Gtk# is package to build GUI applications with the Gtk+ toolkit.
The software is also available on the `Mono' channel in <a href="http://www.ximian.com/products/redcarpet/">Red Carpet</a>.
- Some useful links: the <a
- href="http://www.go-mono.org/faq.html">FAQ</a>.
-
- Packages can find RPM Spec files and other resources in the <a
+ Packagers can find RPM Spec files and other resources in the <a
href="http://www.go-mono.com/packagers/">packagers page</a>.
<table>
<tbody>
<tr bgcolor="#DDDDDD">
<td>
+ <b>Mono 1.0</b><br>
+ <a href="archive/1.0/index.html">Release notes</a><br>
+ June 30th, 2004
+ </td>
+ <td>
+ <table cellspacing="1" cellpadding="3">
+ <tr bgcolor="#BBBBBB">
+ <td>
+ <b>Source Code</b>
+ </td>
+ <td>
+ <ul>
+ <li><a href="archive/1.0/mono-1.0.tar.gz">Mono Runtime 1.0</a>
+ <li><a href="archive/1.0/mcs-1.0.tar.gz">Mono Class Libraries and C# Compiler 1.0</a>
+ <li><a href="archive/1.0/libgdiplus-1.0.tar.gz">libgdiplus 1.0</a>
+ <p>
+ <li><a href="archive/1.0/monodoc-1.0.tar.gz">MonoDoc 1.0</a>
+ <li><a href="archive/1.0/xsp-1.0.tar.gz">XSP web server 1.0</a>
+ <li><a href="archive/1.0/mod_mono-1.0.tar.gz">Apache Mono module 1.0</a>
+ <p>
+ <li><a href="archive/1.0/winelib-0.3.tar.gz">Winelib 0.3</a>
+ <p>
+ <li><a href="archive/1.0/gtk-sharp-1.0.tar.gz">Gtk# 1.0</a>
+ <li><a href="archive/1.0/gecko-sharp-0.5.tar.gz">Gecko# 0.5</a>
+ <li><a href="archive/1.0/gtksourceview-sharp-0.5.tar.gz">Gtk SourceView# 0.5</a>
+ <li><a href="archive/1.0/monodevelop-0.5.tar.gz">MonoDevelop IDE 0.5</a>
+ </ul>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/redhat-36.gif"><b>Red Hat 9.0/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/redhat-9-i386">Packages</a>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/redhat-36.gif"><b>Fedora Core 1/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/fedora-1-i386">Packages</a>
+ <p><a href="http://www.go-mono.com/archive/yum-repository/fedora-1-i386">YUM Repository</a>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/redhat-36.gif"><b>Fedora Core 2/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/fedora-2-i386">Packages</a>
+ <p><a href="http://www.go-mono.com/archive/yum-repository/fedora-2-i386">YUM Repository</a>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/suse-36.gif"><b>SLES 8/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/sles-8-i386/">Packages</a>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/suse-36.gif"><b>SUSE 9/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/suse-90-i586/">Packages</a>
+ </td>
+ </tr>
+ <tr bgcolor="#bbbbbb">
+ <td bgcolor="#999999">
+ <img src="images/suse-36.gif"><b>SUSE 9.1/x86</b><br>
+ </td>
+ <td>
+ <a href="archive/1.0/suse-91-i586/">Packages</a>
+ </td>
+ </tr>
+ <tr>
+ <td bgcolor="#999999">
+ <div align="left"><img src="images/windows-36.gif"></div>
+ <div align="right"><b>Windows installer</b><br><small>Win2k and above</small></div>
+ </td>
+ <td>
+ <a href="archive/1.0/windows/mono-1.0-win32-1.exe">Mono Setup</a>
+ </td>
+ </tr>
+ <tr>
+ <td bgcolor="#999999">
+ <img src="images/macos-36.gif"><b>Mac OS X package</b>
+ </td>
+ <td>
+ <a href="archive/1.0/macos/MonoFramework-1.0.dmg">MonoFramework-1.0.dmg</a> in /Library/Framework
+ </td>
+ </tr>
+ </table>
+ </td>
+ </table>
+
+ <hr>
+
+ <table>
+ <tbody>
+ <tr bgcolor="#DDDDDD">
+ <td>
<b>Release Candidate</b><br>
<!-- <a href="archive/beta3/beta3.html">Release notes</a><br> -->
June 25th, 2004
diff --git a/web/index b/web/index
index d701c09c4d5..52a8ced8b09 100644
--- a/web/index
+++ b/web/index
@@ -1,3 +1,4 @@
+<meta http-equiv="Refresh" content="0"; URL=http://www.mono-project.com/">
<link rel="alternate" type="application/rss+xml" title="RSS" href="index.rss"/>
@@ -174,6 +175,26 @@
</a> Wikis.
</p>
+@item Jun 30th, 2004: Mono 1.0
+
+ <table>
+ <tr>
+ <td>
+ <img
+ src="http://www.go-mono.com/archive/1.0/mono1.gif"></td>
+ <td>
+ <b>Mono 1.0 has been released!</b><br/>
+
+ <p>Be the first kid in your block to install the
+ <i>it-took-us-three-years-but-we-did-it</i> development platform.
+
+ <p>Read the <a
+ href="http://www.go-mono.com/archive/1.0/index.html">release notes</a>
+ or <a href="http://www.go-mono.com/download.html">download it</a></p>
+ </td>
+ </tr>
+ </table>
+
@item Jun 23rd, 2004: The Mono Hackers Hall of Fame welcomes John Luke, Dan Morgan and Tim Coleman.
The <a href="http://www.go-mono.com/hackers.html">Mono Hackers Hall Of Fame</a>