* Syscall.cs: Update comment specifying which functions belong in Syscall.
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixMarshal.cs
index 7d89e8b24dd21bb2c361c70f3b8fcdf23d7a4984..7d5e5e61ff4147529e648d611d797d612748112e 100644 (file)
@@ -66,10 +66,10 @@ namespace Mono.Unix {
                {
                        try {
                                Translate = new ErrorTranslator (strerror_r);
-                               string ignore = Translate (Error.EPERM);
+                               Translate (Error.ERANGE);
                                HaveStrerror_r = true;
                        }
-                       catch (MissingMethodException e) {
+                       catch (EntryPointNotFoundException e) {
                                Translate = new ErrorTranslator (strerror);
                                HaveStrerror_r = false;
                        }
@@ -77,7 +77,7 @@ namespace Mono.Unix {
 
                private static string strerror (Error errno)
                {
-                       return Syscall.strerror (errno);
+                       return Stdlib.strerror (errno);
                }
 
                private static string strerror_r (Error errno)
@@ -87,7 +87,7 @@ namespace Mono.Unix {
                        do {
                                buf.Capacity *= 2;
                                r = Syscall.strerror_r (errno, buf);
-                       } while (r == -1 && Syscall.GetLastError() == Error.ERANGE);
+                       } while (r == -1 && Stdlib.GetLastError() == Error.ERANGE);
 
                        if (r == -1)
                                return "** Unknown error code: " + ((int) errno) + "**";
@@ -161,11 +161,9 @@ namespace Mono.Unix {
 
                private static int CountStrings (IntPtr stringArray)
                {
-                       int count = -1;
-                       IntPtr item = Marshal.ReadIntPtr (stringArray, count * IntPtr.Size);
-                       do {
+                       int count = 0;
+                       while (Marshal.ReadIntPtr (stringArray, count*IntPtr.Size) != IntPtr.Zero)
                                ++count;
-                       } while (Marshal.ReadIntPtr (stringArray, count * IntPtr.Size) != IntPtr.Zero);
                        return count;
                }
 
@@ -196,7 +194,7 @@ namespace Mono.Unix {
 
                public static bool ShouldRetrySyscall (int r)
                {
-                       if (r == -1 && Syscall.GetLastError () == Error.EINTR)
+                       if (r == -1 && Stdlib.GetLastError () == Error.EINTR)
                                return true;
                        return false;
                }
@@ -204,12 +202,49 @@ namespace Mono.Unix {
                public static bool ShouldRetrySyscall (int r, out Error error)
                {
                        error = (Error) 0;
-                       if (r == -1 && (error = Syscall.GetLastError ()) == Error.EINTR)
+                       if (r == -1 && (error = Stdlib.GetLastError ()) == Error.EINTR)
                                return true;
                        return false;
                }
 
-               private static Exception CreateExceptionForError (Error errno)
+               // we can't permit any printf(3)-style formatting information, since that
+               // would kill the stack.  However, replacing %% is silly, and some %* are
+               // permitted (such as %m in syslog to print strerror(errno)).
+               internal static string EscapeFormatString (string message, 
+                               char [] permitted)
+               {
+                       if (message == null)
+                               return "";
+                       StringBuilder sb = new StringBuilder (message.Length);
+                       for (int i = 0; i < message.Length; ++i) {
+                               char c = message [i];
+                               sb.Append (c);
+                               if (c == '%' && (i+1) < message.Length) {
+                                       char n = message [i+1];
+                                       if (n == '%' || IsCharPresent (permitted, n))
+                                               sb.Append (n);
+                                       else
+                                               sb.Append ('%').Append (n);
+                                       ++i;
+                               }
+                               // invalid format string: % at EOS.
+                               else if (c == '%')
+                                       sb.Append ('%');
+                       }
+                       return sb.ToString ();
+               }
+
+               private static bool IsCharPresent (char[] array, char c)
+               {
+                       if (array == null)
+                               return false;
+                       for (int i = 0; i < array.Length; ++i)
+                               if (array [i] == c)
+                                       return true;
+                       return false;
+               }
+
+               internal static Exception CreateExceptionForError (Error errno)
                {
                        string message = GetErrorDescription (errno);
                        UnixIOException p = new UnixIOException (errno);
@@ -231,6 +266,11 @@ namespace Mono.Unix {
                        return p;
                }
 
+               internal static Exception CreateExceptionForLastError ()
+               {
+                       return CreateExceptionForError (Stdlib.GetLastError());
+               }
+
                public static void ThrowExceptionForError (Error errno)
                {
                        throw CreateExceptionForError (errno);
@@ -238,7 +278,7 @@ namespace Mono.Unix {
 
                public static void ThrowExceptionForLastError ()
                {
-                       throw CreateExceptionForError (Syscall.GetLastError());
+                       throw CreateExceptionForLastError ();
                }
 
                public static void ThrowExceptionForErrorIf (int retval, Error errno)