public static Errno GetLastError ()
{
- int errno = Marshal.GetLastWin32Error ();
- return NativeConvert.ToErrno (errno);
+ if (Environment.OSVersion.Platform != PlatformID.Unix) {
+ // On Windows Marshal.GetLastWin32Error() doesn't take errno
+ // into account so we need to call Mono_Posix_Stdlib_GetLastError()
+ // which returns the value of errno in the C runtime
+ // libMonoPosixHelper.dll was linked against.
+ return (Errno) _GetLastError ();
+ }
+ return NativeConvert.ToErrno (Marshal.GetLastWin32Error ());
}
+ [DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
+ EntryPoint="Mono_Posix_Stdlib_GetLastError")]
+ private static extern int _GetLastError ();
+
[DllImport (MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Posix_Stdlib_SetLastError")]
private static extern void SetLastError (int error);
EntryPoint="Mono_Posix_Syscall_get_at_fdcwd")]
private static extern int get_at_fdcwd ();
- public static readonly int AT_FDCWD = get_at_fdcwd ();
+ public static int AT_FDCWD { get { return get_at_fdcwd (); } }
#endregion
[DllImport (MPH, EntryPoint="Mono_Posix_Syscall_L_ctermid")]
private static extern int _L_ctermid ();
- public static readonly int L_ctermid = _L_ctermid ();
+ public static int L_ctermid { get { return _L_ctermid (); } }
[DllImport (MPH, EntryPoint="Mono_Posix_Syscall_L_cuserid")]
private static extern int _L_cuserid ();
- public static readonly int L_cuserid = _L_cuserid ();
+ public static int L_cuserid { get { return _L_cuserid (); } }
internal static object getlogin_lock = new object ();
EntryPoint="Mono_Posix_Syscall_get_utime_omit")]
private static extern long get_utime_omit ();
- public static readonly long UTIME_NOW = get_utime_now ();
+ public static long UTIME_NOW { get { return get_utime_now (); } }
- public static readonly long UTIME_OMIT = get_utime_omit ();
+ public static long UTIME_OMIT { get { return get_utime_omit (); } }
[DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_futimens")]
[TestFixture]
public class StdioFileStreamTest {
- string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.Mono.Unix.Tests");
+ static string BaseTempFolder = Path.Combine (Path.GetTempPath (),
+ "MonoTests.Mono.Unix.Tests");
+ static string TempFolder;
static readonly char DSC = Path.DirectorySeparatorChar;
- [TearDown]
- public void TearDown()
+ [TestFixtureSetUp]
+ public void FixtureSetUp ()
{
- if (Directory.Exists (TempFolder))
- Directory.Delete (TempFolder, true);
+ try {
+ // Try to cleanup from any previous NUnit run.
+ Directory.Delete (BaseTempFolder, true);
+ } catch (Exception) {
+ }
}
[SetUp]
public void SetUp ()
{
- if (Directory.Exists (TempFolder))
- Directory.Delete (TempFolder, true);
-
+ int i = 0;
+ do {
+ TempFolder = Path.Combine (BaseTempFolder, (++i).ToString());
+ } while (Directory.Exists (TempFolder));
Directory.CreateDirectory (TempFolder);
}
+ [TearDown]
+ public void TearDown ()
+ {
+ try {
+ // This might throw an exception on Windows
+ // since the directory may contain open files.
+ Directory.Delete (TempFolder, true);
+ } catch (Exception e) {
+ Console.WriteLine (e);
+ }
+ }
+
public void TestCtr ()
{
string path = TempFolder + DSC + "testfilestream.tmp.1";
{
StdioFileStream fs = null;
StdioFileStream fs2 = null;
- string tempPath = Path.Combine (Path.GetTempPath (), "temp");
+ string tempPath = Path.Combine (TempFolder, "temp");
try {
if (!File.Exists (tempPath)) {
TextWriter tw = File.CreateText (tempPath);
fs.Close ();
if (fs2 != null)
fs2.Close ();
- if (File.Exists (tempPath))
- File.Delete (tempPath);
}
}
stream.Write (outbytes, 7, 7);
stream.Write (outbytes, 14, 1);
- stream.Read (bytes, 0, 15);
stream.Seek (15, SeekOrigin.Begin);
+ Array.Clear (bytes, 0, bytes.Length);
+ stream.Read (bytes, 0, 15);
for (int i = 0; i < 15; ++i)
Assert.AreEqual (i + 1, bytes [i]);
stream.Close ();
Mono_Posix_Stdlib_EXIT_SUCCESS\r
Mono_Posix_Stdlib_FILENAME_MAX\r
Mono_Posix_Stdlib_FOPEN_MAX\r
+Mono_Posix_Stdlib_GetLastError\r
Mono_Posix_Stdlib_InvokeSignalHandler\r
Mono_Posix_Stdlib_L_tmpnam\r
Mono_Posix_Stdlib_MB_CUR_MAX\r
if [[ ${label} == w* ]]; then ${TESTCMD} --label=Mono.Data.Sqlite --skip; else ${TESTCMD} --label=Mono.Data.Sqlite --timeout=5m make -w -C mcs/class/Mono.Data.Sqlite run-test; fi
${TESTCMD} --label=System.Data.OracleClient --timeout=5m make -w -C mcs/class/System.Data.OracleClient run-test;
${TESTCMD} --label=System.Design --timeout=5m make -w -C mcs/class/System.Design run-test;
-if [[ -n "${ghprbPullId}" ]] && [[ ${label} == w* ]]; then ${TESTCMD} --label=Mono.Posix --skip; else ${TESTCMD} --label=Mono.Posix --timeout=5m make -w -C mcs/class/Mono.Posix run-test; fi
+${TESTCMD} --label=Mono.Posix --timeout=5m make -w -C mcs/class/Mono.Posix run-test
${TESTCMD} --label=System.Web --timeout=30m make -w -C mcs/class/System.Web run-test
${TESTCMD} --label=System.Web.Services --timeout=5m make -w -C mcs/class/System.Web.Services run-test
${TESTCMD} --label=System.Runtime.SFS --timeout=5m make -w -C mcs/class/System.Runtime.Serialization.Formatters.Soap run-test;
G_BEGIN_DECLS
+int
+Mono_Posix_Stdlib_GetLastError (void)
+{
+ return errno;
+}
+
void
Mono_Posix_Stdlib_SetLastError (int error_number)
{
int Mono_Posix_FromSeekFlags (short x, short *r)
{
*r = 0;
- if (x == Mono_Posix_SeekFlags_L_INCR)
#ifdef L_INCR
+ if (x == Mono_Posix_SeekFlags_L_INCR)
{*r = L_INCR; return 0;}
-#else /* def L_INCR */
- {errno = EINVAL; return -1;}
-#endif /* ndef L_INCR */
- if (x == Mono_Posix_SeekFlags_L_SET)
+#endif /* def L_INCR */
#ifdef L_SET
+ if (x == Mono_Posix_SeekFlags_L_SET)
{*r = L_SET; return 0;}
-#else /* def L_SET */
- {errno = EINVAL; return -1;}
-#endif /* ndef L_SET */
- if (x == Mono_Posix_SeekFlags_L_XTND)
+#endif /* def L_SET */
#ifdef L_XTND
+ if (x == Mono_Posix_SeekFlags_L_XTND)
{*r = L_XTND; return 0;}
-#else /* def L_XTND */
- {errno = EINVAL; return -1;}
-#endif /* ndef L_XTND */
- if (x == Mono_Posix_SeekFlags_SEEK_CUR)
+#endif /* def L_XTND */
#ifdef SEEK_CUR
+ if (x == Mono_Posix_SeekFlags_SEEK_CUR)
{*r = SEEK_CUR; return 0;}
-#else /* def SEEK_CUR */
- {errno = EINVAL; return -1;}
-#endif /* ndef SEEK_CUR */
- if (x == Mono_Posix_SeekFlags_SEEK_END)
+#endif /* def SEEK_CUR */
#ifdef SEEK_END
+ if (x == Mono_Posix_SeekFlags_SEEK_END)
{*r = SEEK_END; return 0;}
-#else /* def SEEK_END */
- {errno = EINVAL; return -1;}
-#endif /* ndef SEEK_END */
- if (x == Mono_Posix_SeekFlags_SEEK_SET)
+#endif /* def SEEK_END */
#ifdef SEEK_SET
+ if (x == Mono_Posix_SeekFlags_SEEK_SET)
{*r = SEEK_SET; return 0;}
-#else /* def SEEK_SET */
- {errno = EINVAL; return -1;}
-#endif /* ndef SEEK_SET */
- if (x == 0)
- return 0;
+#endif /* def SEEK_SET */
errno = EINVAL; return -1;
}
int Mono_Posix_ToSeekFlags (short x, short *r)
{
*r = 0;
- if (x == 0)
- return 0;
#ifdef L_INCR
if (x == L_INCR)
{*r = Mono_Posix_SeekFlags_L_INCR; return 0;}
void Mono_Posix_Stdlib_free (void* p);
int Mono_Posix_Stdlib_rewind (void* stream);
int Mono_Posix_Stdlib_setbuf (void* stream, void* buf);
+int Mono_Posix_Stdlib_GetLastError (void);
void Mono_Posix_Stdlib_SetLastError (int error);
int Mono_Posix_Stdlib_setvbuf (void* stream, void* buf, int mode, guint64 size);
void* Mono_Posix_Stdlib_fopen (char* path, char* mode);
mph_return_if_size_t_overflow (size);
mph_return_if_size_t_overflow (nmemb);
- return fwrite (ptr, (size_t) size, (size_t) nmemb, (FILE*) stream);
+ size_t ret = fwrite (ptr, (size_t) size, (size_t) nmemb, (FILE*) stream);
+#ifdef HOST_WIN32
+ // Workaround for a particular weirdness on Windows triggered by the
+ // StdioFileStreamTest.Write() test method. The test writes 15 bytes to a
+ // file, then rewinds the file pointer and reads the same bytes. It then
+ // writes 15 additional bytes to the file. This second write fails on
+ // Windows with 0 returned from fwrite(). Calling fseek() followed by a retry
+ // of fwrite() like we do here fixes the issue.
+ if (ret != nmemb)
+ {
+ fseek (stream, 0, SEEK_CUR);
+ ret = fwrite (ptr + (ret * nmemb), (size_t) size, (size_t) nmemb - ret, (FILE*) stream);
+ }
+#endif
+ return ret;
}
#ifdef HAVE_VSNPRINTF