huge refactoring

This commit is contained in:
BlubbFish 2019-11-26 18:15:10 +01:00
parent 6b5d3e07cc
commit 2f0ae844d0
56 changed files with 15671 additions and 15714 deletions

View File

@ -1,3 +1,5 @@
using System;
// //
// Consts.cs.in // Consts.cs.in
// //
@ -30,7 +32,7 @@
static partial class Consts static partial class Consts
{ {
public const string MonoCorlibVersion = "@MONO_CORLIB_VERSION@"; public const String MonoCorlibVersion = "@MONO_CORLIB_VERSION@";
} }
#if !NETCORE #if !NETCORE
@ -41,10 +43,10 @@ static partial class Consts
// Use these assembly version constants to make code more maintainable. // Use these assembly version constants to make code more maintainable.
// //
public const string MonoVersion = "@MONO_VERSION@"; public const String MonoVersion = "@MONO_VERSION@";
public const string MonoCompany = "Mono development team"; public const String MonoCompany = "Mono development team";
public const string MonoProduct = "Mono Common Language Infrastructure"; public const String MonoProduct = "Mono Common Language Infrastructure";
public const string MonoCopyright = "(c) Various Mono authors"; public const String MonoCopyright = "(c) Various Mono authors";
#if MOBILE #if MOBILE
// Versions of .NET Framework for Silverlight 4.0 // Versions of .NET Framework for Silverlight 4.0
@ -55,12 +57,12 @@ static partial class Consts
public const string VsFileVersion = "9.0.50727.42"; // unused, but needed for compilation public const string VsFileVersion = "9.0.50727.42"; // unused, but needed for compilation
#elif NET_4_6 #elif NET_4_6
public const string FxVersion = "4.0.0.0"; public const String FxVersion = "4.0.0.0";
public const string FxFileVersion = "4.6.57.0"; public const String FxFileVersion = "4.6.57.0";
public const string EnvironmentVersion = "4.0.30319.42000"; public const String EnvironmentVersion = "4.0.30319.42000";
public const string VsVersion = "0.0.0.0"; // Useless ? public const String VsVersion = "0.0.0.0"; // Useless ?
public const string VsFileVersion = "11.0.0.0"; // TODO: public const String VsFileVersion = "11.0.0.0"; // TODO:
#elif NET_4_5 #elif NET_4_5
public const string FxVersion = "4.0.0.0"; public const string FxVersion = "4.0.0.0";
public const string FxFileVersion = "4.0.30319.17020"; public const string FxFileVersion = "4.0.30319.17020";
@ -94,43 +96,43 @@ static partial class Consts
#if MOBILE #if MOBILE
const string PublicKeyToken = "7cec85d7bea7798e"; const string PublicKeyToken = "7cec85d7bea7798e";
#else #else
const string PublicKeyToken = "b77a5c561934e089"; const String PublicKeyToken = "b77a5c561934e089";
#endif #endif
// //
// Use these assembly name constants to make code more maintainable. // Use these assembly name constants to make code more maintainable.
// //
public const string AssemblyI18N = "I18N, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const String AssemblyI18N = "I18N, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756";
public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=" + VsVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=" + VsVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=" + VsVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=" + VsVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblyMono_Http = "Mono.Http, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const String AssemblyMono_Http = "Mono.Http, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756";
public const string AssemblyMono_Posix = "Mono.Posix, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const String AssemblyMono_Posix = "Mono.Posix, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756";
public const string AssemblyMono_Security = "Mono.Security, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const String AssemblyMono_Security = "Mono.Security, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756";
public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const String AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=0738eb9f132ed756";
public const string AssemblyCorlib = "mscorlib, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken; public const String AssemblyCorlib = "mscorlib, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken;
public const string AssemblySystem = "System, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken; public const String AssemblySystem = "System, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken;
public const string AssemblySystem_Data = "System.Data, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const String AssemblySystem_Data = "System.Data, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089";
public const string AssemblySystem_Design = "System.Design, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Design = "System.Design, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Drawing = "System.Drawing, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Drawing = "System.Drawing, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Messaging = "System.Messaging, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Messaging = "System.Messaging, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Security = "System.Security, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Security = "System.Security, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Web = "System.Web, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const String AssemblySystem_Web = "System.Web, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const String AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089";
public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const String AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const String AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
public const string AssemblySystem_Core = "System.Core, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken; public const String AssemblySystem_Core = "System.Core, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=" + PublicKeyToken;
public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35"; public const String WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35";
public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const String AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const String AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const String AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const String AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const String AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
} }
#endif #endif

View File

@ -39,13 +39,7 @@ internal sealed class Locale {
{ {
} }
public static string GetText (string msg) public static String GetText(String msg) => msg;
{
return msg;
}
public static string GetText (string fmt, params object [] args) public static String GetText(String fmt, params Object[] args) => String.Format(fmt, args);
{
return String.Format (fmt, args);
}
} }

View File

@ -31,6 +31,7 @@
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Mono.Posix { namespace Mono.Posix {
@ -38,11 +39,14 @@ namespace Mono.Posix {
[Obsolete ("Use Mono.Unix.Catalog")] [Obsolete ("Use Mono.Unix.Catalog")]
public class Catalog { public class Catalog {
[DllImport("intl")] [DllImport("intl")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname); static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
[DllImport("intl")] [DllImport("intl")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr bind_textdomain_codeset (IntPtr domainname, static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
IntPtr codeset); IntPtr codeset);
[DllImport("intl")] [DllImport("intl")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr textdomain (IntPtr domainname); static extern IntPtr textdomain (IntPtr domainname);
public static void Init (String package, String localedir) public static void Init (String package, String localedir)
@ -50,15 +54,16 @@ namespace Mono.Posix {
IntPtr ipackage = Marshal.StringToHGlobalAuto (package); IntPtr ipackage = Marshal.StringToHGlobalAuto (package);
IntPtr ilocaledir = Marshal.StringToHGlobalAuto (localedir); IntPtr ilocaledir = Marshal.StringToHGlobalAuto (localedir);
IntPtr iutf8 = Marshal.StringToHGlobalAuto ("UTF-8"); IntPtr iutf8 = Marshal.StringToHGlobalAuto ("UTF-8");
bindtextdomain (ipackage, ilocaledir); _ = bindtextdomain(ipackage, ilocaledir);
bind_textdomain_codeset (ipackage, iutf8); _ = bind_textdomain_codeset(ipackage, iutf8);
textdomain (ipackage); _ = textdomain(ipackage);
Marshal.FreeHGlobal (ipackage); Marshal.FreeHGlobal (ipackage);
Marshal.FreeHGlobal (ilocaledir); Marshal.FreeHGlobal (ilocaledir);
Marshal.FreeHGlobal (iutf8); Marshal.FreeHGlobal (iutf8);
} }
[DllImport("intl")] [DllImport("intl")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr gettext (IntPtr instring); static extern IntPtr gettext (IntPtr instring);
public static String GetString (String s) public static String GetString (String s)
@ -70,6 +75,7 @@ namespace Mono.Posix {
} }
[DllImport("intl")] [DllImport("intl")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n); static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n);
public static String GetPluralString (String s, String p, Int32 n) public static String GetPluralString (String s, String p, Int32 n)

View File

@ -35,9 +35,9 @@ namespace Mono.Posix
{ {
#pragma warning disable 649 #pragma warning disable 649
internal struct PeerCredData { internal struct PeerCredData {
public int pid; public Int32 pid;
public int uid; public Int32 uid;
public int gid; public Int32 gid;
} }
#pragma warning restore 649 #pragma warning restore 649
@ -48,7 +48,7 @@ namespace Mono.Posix
* SocketOptionName, and keep it synchronised with the * SocketOptionName, and keep it synchronised with the
* runtime * runtime
*/ */
private const int so_peercred=10001; private const Int32 so_peercred =10001;
private PeerCredData data; private PeerCredData data;
public PeerCred (Socket sock) { public PeerCred (Socket sock) {
@ -56,26 +56,14 @@ namespace Mono.Posix
throw new ArgumentException ("Only Unix sockets are supported", "sock"); throw new ArgumentException ("Only Unix sockets are supported", "sock");
} }
data = (PeerCredData)sock.GetSocketOption (SocketOptionLevel.Socket, (SocketOptionName)so_peercred); this.data = (PeerCredData)sock.GetSocketOption (SocketOptionLevel.Socket, (SocketOptionName)so_peercred);
} }
public int ProcessID { public Int32 ProcessID => this.data.pid;
get {
return(data.pid);
}
}
public int UserID { public Int32 UserID => this.data.uid;
get {
return(data.uid);
}
}
public int GroupID { public Int32 GroupID => this.data.gid;
get {
return(data.gid);
}
}
} }
} }

View File

@ -65,11 +65,12 @@
using System; using System;
using System.Text; using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
namespace Mono.Posix { namespace Mono.Posix {
[Flags] [Flags]
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.OpenFlags")] [Obsolete ("Use Mono.Unix.Native.OpenFlags")]
public enum OpenFlags { public enum OpenFlags {
// //
@ -103,7 +104,7 @@ namespace Mono.Posix {
} }
[Flags] [Flags]
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.FilePermissions")] [Obsolete ("Use Mono.Unix.Native.FilePermissions")]
public enum FileMode { public enum FileMode {
S_ISUID = 2048, S_ISUID = 2048,
@ -121,7 +122,7 @@ namespace Mono.Posix {
} }
[Flags] [Flags]
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.WaitOptions")] [Obsolete ("Use Mono.Unix.Native.WaitOptions")]
public enum WaitOptions { public enum WaitOptions {
WNOHANG, WNOHANG,
@ -129,7 +130,7 @@ namespace Mono.Posix {
} }
[Flags] [Flags]
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.AccessModes")] [Obsolete ("Use Mono.Unix.Native.AccessModes")]
public enum AccessMode { public enum AccessMode {
R_OK = 1, R_OK = 1,
@ -139,7 +140,7 @@ namespace Mono.Posix {
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.Signum")] [Obsolete ("Use Mono.Unix.Native.Signum")]
public enum Signals { public enum Signals {
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS,
@ -153,67 +154,82 @@ namespace Mono.Posix {
// SIGRTMIN // SIGRTMIN
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
[Obsolete ("Use Mono.Unix.Native.Syscall.")] [Obsolete ("Use Mono.Unix.Native.Syscall.")]
public class Syscall { public class Syscall {
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int exit (int status); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 exit (Int32 status);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int fork (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 fork ();
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public unsafe static extern IntPtr read (int fileDescriptor, void *buf, IntPtr count); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public unsafe static extern IntPtr read (Int32 fileDescriptor, void *buf, IntPtr count);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public unsafe static extern IntPtr write (int fileDescriptor, void *buf, IntPtr count); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public unsafe static extern IntPtr write (Int32 fileDescriptor, void *buf, IntPtr count);
[DllImport ("libc", EntryPoint="open", SetLastError=true)] [DllImport ("libc", EntryPoint="open", SetLastError=true)]
internal static extern int syscall_open (string pathname, int flags, int mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal static extern Int32 syscall_open (String pathname, Int32 flags, Int32 mode);
[DllImport ("MonoPosixHelper")] [DllImport ("MonoPosixHelper")]
internal extern static int map_Mono_Posix_OpenFlags (OpenFlags flags); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 map_Mono_Posix_OpenFlags (OpenFlags flags);
[DllImport ("MonoPosixHelper")] [DllImport ("MonoPosixHelper")]
internal extern static int map_Mono_Posix_FileMode (FileMode mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 map_Mono_Posix_FileMode (FileMode mode);
public static int open (string pathname, OpenFlags flags) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static Int32 open (String pathname, OpenFlags flags)
{ {
if ((flags & OpenFlags.O_CREAT) != 0) if ((flags & OpenFlags.O_CREAT) != 0) {
throw new ArgumentException ("If you pass O_CREAT, you must call the method with the mode flag"); throw new ArgumentException ("If you pass O_CREAT, you must call the method with the mode flag");
}
int posix_flags = map_Mono_Posix_OpenFlags (flags); Int32 posix_flags = map_Mono_Posix_OpenFlags (flags);
return syscall_open (pathname, posix_flags, 0); return syscall_open (pathname, posix_flags, 0);
} }
public static int open (string pathname, OpenFlags flags, FileMode mode) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static Int32 open (String pathname, OpenFlags flags, FileMode mode)
{ {
int posix_flags = map_Mono_Posix_OpenFlags (flags); Int32 posix_flags = map_Mono_Posix_OpenFlags (flags);
int posix_mode = map_Mono_Posix_FileMode (mode); Int32 posix_mode = map_Mono_Posix_FileMode (mode);
return syscall_open (pathname, posix_flags, posix_mode); return syscall_open (pathname, posix_flags, posix_mode);
} }
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int close (int fileDescriptor); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 close (Int32 fileDescriptor);
[DllImport ("libc", EntryPoint="waitpid", SetLastError=true)] [DllImport ("libc", EntryPoint="waitpid", SetLastError=true)]
unsafe internal static extern int syscall_waitpid (int pid, int * status, int options); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
unsafe internal static extern Int32 syscall_waitpid (Int32 pid, Int32* status, Int32 options);
[DllImport ("MonoPosixHelper")] [DllImport ("MonoPosixHelper")]
internal extern static int map_Mono_Posix_WaitOptions (WaitOptions wait_options); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 map_Mono_Posix_WaitOptions (WaitOptions wait_options);
public static int waitpid (int pid, out int status, WaitOptions options) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static Int32 waitpid (Int32 pid, out Int32 status, WaitOptions options)
{ {
unsafe { unsafe {
int s = 0; Int32 s = 0;
int r = syscall_waitpid (pid, &s, map_Mono_Posix_WaitOptions (options)); Int32 r = syscall_waitpid (pid, &s, map_Mono_Posix_WaitOptions (options));
status = s; status = s;
return r; return r;
} }
} }
public static int waitpid (int pid, WaitOptions options) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static Int32 waitpid (Int32 pid, WaitOptions options)
{ {
unsafe { unsafe {
return syscall_waitpid (pid, null, map_Mono_Posix_WaitOptions (options)); return syscall_waitpid (pid, null, map_Mono_Posix_WaitOptions (options));
@ -221,185 +237,218 @@ namespace Mono.Posix {
} }
[DllImport ("MonoPosixHelper", EntryPoint="wifexited")] [DllImport ("MonoPosixHelper", EntryPoint="wifexited")]
public static extern int WIFEXITED (int status); public static extern Int32 WIFEXITED (Int32 status);
[DllImport ("MonoPosixHelper", EntryPoint="wexitstatus")] [DllImport ("MonoPosixHelper", EntryPoint="wexitstatus")]
public static extern int WEXITSTATUS (int status); public static extern Int32 WEXITSTATUS (Int32 status);
[DllImport ("MonoPosixHelper", EntryPoint="wifsignaled")] [DllImport ("MonoPosixHelper", EntryPoint="wifsignaled")]
public static extern int WIFSIGNALED (int status); public static extern Int32 WIFSIGNALED (Int32 status);
[DllImport ("MonoPosixHelper", EntryPoint="wtermsig")] [DllImport ("MonoPosixHelper", EntryPoint="wtermsig")]
public static extern int WTERMSIG (int status); public static extern Int32 WTERMSIG (Int32 status);
[DllImport ("MonoPosixHelper", EntryPoint="wifstopped")] [DllImport ("MonoPosixHelper", EntryPoint="wifstopped")]
public static extern int WIFSTOPPED (int status); public static extern Int32 WIFSTOPPED (Int32 status);
[DllImport ("MonoPosixHelper", EntryPoint="wstopsig")] [DllImport ("MonoPosixHelper", EntryPoint="wstopsig")]
public static extern int WSTOPSIG (int status); public static extern Int32 WSTOPSIG (Int32 status);
[DllImport ("libc", EntryPoint="creat", SetLastError=true)] [DllImport ("libc", EntryPoint="creat", SetLastError=true)]
internal static extern int syscall_creat (string pathname, int flags); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal static extern Int32 syscall_creat (String pathname, Int32 flags);
public static int creat (string pathname, FileMode flags) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static Int32 creat(String pathname, FileMode flags) => syscall_creat(pathname, map_Mono_Posix_FileMode(flags));
return syscall_creat (pathname, map_Mono_Posix_FileMode (flags));
}
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int link (string oldPath, string newPath); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 link (String oldPath, String newPath);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int unlink (string path); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 unlink (String path);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int symlink (string oldpath, string newpath); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 symlink (String oldpath, String newpath);
// TODO: execve // TODO: execve
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int chdir (string path); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 chdir (String path);
// TODO: time // TODO: time
// TODO: mknod // TODO: mknod
[DllImport ("libc", EntryPoint="chmod", SetLastError=true)] [DllImport ("libc", EntryPoint="chmod", SetLastError=true)]
internal static extern int syscall_chmod (string path, int mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal static extern Int32 syscall_chmod (String path, Int32 mode);
public static int chmod (string path, FileMode mode) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static Int32 chmod(String path, FileMode mode) => syscall_chmod(path, map_Mono_Posix_FileMode(mode));
return syscall_chmod (path, map_Mono_Posix_FileMode (mode));
}
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int chown (string path, int owner, int group); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 chown (String path, Int32 owner, Int32 group);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int lchown (string path, int owner, int group); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 lchown (String path, Int32 owner, Int32 group);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int lseek (int fileDescriptor, int offset, int whence); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 lseek (Int32 fileDescriptor, Int32 offset, Int32 whence);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getpid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getpid ();
// TODO: mount // TODO: mount
// TODO: umount // TODO: umount
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setuid (int uid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setuid (Int32 uid);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getuid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getuid ();
// TODO: stime // TODO: stime
// TODO: ptrace // TODO: ptrace
[DllImport ("libc")] [DllImport ("libc")]
public static extern uint alarm (uint seconds); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern UInt32 alarm (UInt32 seconds);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int pause (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 pause ();
// TODO: utime // TODO: utime
[DllImport ("libc", EntryPoint="access", SetLastError=true)] [DllImport ("libc", EntryPoint="access", SetLastError=true)]
internal extern static int syscall_access (string pathname, int mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 syscall_access (String pathname, Int32 mode);
[DllImport ("MonoPosixHelper")] [DllImport ("MonoPosixHelper")]
internal extern static int map_Mono_Posix_AccessMode (AccessMode mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 map_Mono_Posix_AccessMode (AccessMode mode);
public static int access (string pathname, AccessMode mode) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static Int32 access(String pathname, AccessMode mode) => syscall_access(pathname, map_Mono_Posix_AccessMode(mode));
return syscall_access (pathname, map_Mono_Posix_AccessMode (mode));
}
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int nice (int increment); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 nice (Int32 increment);
// TODO: ftime // TODO: ftime
[DllImport ("libc")] [DllImport ("libc")]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern void sync (); public static extern void sync ();
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern void kill (int pid, int sig); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern void kill (Int32 pid, Int32 sig);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int rename (string oldPath, string newPath); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 rename (String oldPath, String newPath);
[DllImport ("libc", EntryPoint="mkdir", SetLastError=true)] [DllImport ("libc", EntryPoint="mkdir", SetLastError=true)]
internal extern static int syscall_mkdir (string pathname, int mode); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal extern static Int32 syscall_mkdir (String pathname, Int32 mode);
public static int mkdir (string pathname, FileMode mode) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static Int32 mkdir(String pathname, FileMode mode) => syscall_mkdir(pathname, map_Mono_Posix_FileMode(mode));
return syscall_mkdir (pathname, map_Mono_Posix_FileMode (mode));
}
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int rmdir (string path); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 rmdir (String path);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int dup (int fileDescriptor); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 dup (Int32 fileDescriptor);
// TODO: pipe // TODO: pipe
// TODO: times // TODO: times
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setgid (int gid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setgid (Int32 gid);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getgid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getgid ();
public delegate void sighandler_t (int v); public delegate void sighandler_t (Int32 v);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int signal (int signum, sighandler_t handler); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 signal (Int32 signum, sighandler_t handler);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int geteuid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 geteuid ();
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getegid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getegid ();
// TODO: fcntl // TODO: fcntl
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setpgid (int pid, int pgid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setpgid (Int32 pid, Int32 pgid);
// TODO: ulimit // TODO: ulimit
[DllImport ("libc")] [DllImport ("libc")]
public static extern int umask (int umask); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 umask (Int32 umask);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int chroot (string path); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 chroot (String path);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int dup2 (int oldFileDescriptor, int newFileDescriptor); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 dup2 (Int32 oldFileDescriptor, Int32 newFileDescriptor);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getppid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getppid ();
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int getpgrp (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 getpgrp ();
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setsid (); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setsid ();
// TODO: sigaction // TODO: sigaction
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setreuid (int ruid, int euid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setreuid (Int32 ruid, Int32 euid);
[DllImport ("libc", SetLastError=true)] [DllImport ("libc", SetLastError=true)]
public static extern int setregid (int rgid, int egid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 setregid (Int32 rgid, Int32 egid);
// these don't exactly match POSIX, but it's a nice way to get user/group names // these don't exactly match POSIX, but it's a nice way to get user/group names
[DllImport ("MonoPosixHelper", SetLastError=true)] [DllImport ("MonoPosixHelper", SetLastError=true)]
private static extern string helper_Mono_Posix_GetUserName (int uid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static extern String helper_Mono_Posix_GetUserName (Int32 uid);
[DllImport ("MonoPosixHelper", SetLastError=true)] [DllImport ("MonoPosixHelper", SetLastError=true)]
private static extern string helper_Mono_Posix_GetGroupName (int gid); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static extern String helper_Mono_Posix_GetGroupName (Int32 gid);
public static string getusername(int uid) { return helper_Mono_Posix_GetUserName(uid); } [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static string getgroupname(int gid) { return helper_Mono_Posix_GetGroupName(gid); } public static String getusername(Int32 uid) => helper_Mono_Posix_GetUserName(uid);
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static String getgroupname(Int32 gid) => helper_Mono_Posix_GetGroupName(gid);
// TODO: sigsuspend // TODO: sigsuspend
// TODO: sigpending // TODO: sigpending
@ -410,60 +459,63 @@ namespace Mono.Posix {
// TODO: settimeofday // TODO: settimeofday
[DllImport ("libc", EntryPoint="gethostname", SetLastError=true)] [DllImport ("libc", EntryPoint="gethostname", SetLastError=true)]
static extern int syscall_gethostname (byte[] p, int len); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern Int32 syscall_gethostname (Byte[] p, Int32 len);
public static string GetHostName () public static String GetHostName ()
{ {
byte [] buf = new byte [256]; Byte[] buf = new Byte[256];
int res = syscall_gethostname (buf, buf.Length); Int32 res = syscall_gethostname (buf, buf.Length);
if (res == -1) if (res == -1) {
return "localhost"; return "localhost";
}
for (res = 0; res < buf.Length; ++res) { for (res = 0; res < buf.Length; ++res) {
if (buf [res] == 0) if (buf [res] == 0) {
break; break;
} }
}
return Encoding.UTF8.GetString (buf, 0, res); return Encoding.UTF8.GetString (buf, 0, res);
} }
[CLSCompliant (false)] //[CLSCompliant(false)]
public static string gethostname () [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static String gethostname() => GetHostName();
return GetHostName ();
}
[DllImport ("libc", EntryPoint="isatty")] [DllImport ("libc", EntryPoint="isatty")]
static extern int syscall_isatty (int desc); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern Int32 syscall_isatty (Int32 desc);
public static bool isatty (int desc) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static Boolean isatty (Int32 desc)
{ {
int res = syscall_isatty (desc); Int32 res = syscall_isatty (desc);
if (res == 1) if (res == 1) {
return true; return true;
else } else {
return false; return false;
} }
}
[DllImport ("MonoPosixHelper")] [DllImport ("MonoPosixHelper")]
internal extern static int helper_Mono_Posix_Stat (string filename, bool dereference, [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
out int device, out int inode, out int mode, internal extern static Int32 helper_Mono_Posix_Stat (String filename, Boolean dereference,
out int nlinks, out int uid, out int gid, out Int32 device, out Int32 inode, out Int32 mode,
out int rdev, out long size, out long blksize, out long blocks, out Int32 nlinks, out Int32 uid, out Int32 gid,
out long atime, out long mtime, out long ctime); out Int32 rdev, out Int64 size, out Int64 blksize, out Int64 blocks,
out Int64 atime, out Int64 mtime, out Int64 ctime);
private static int stat2(string filename, bool dereference, out Stat stat) { [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
int device, inode, mode; private static Int32 stat2(String filename, Boolean dereference, out Stat stat) {
int nlinks, uid, gid, rdev;
long size, blksize, blocks;
long atime, mtime, ctime;
int ret = helper_Mono_Posix_Stat(filename, dereference, Int32 ret = helper_Mono_Posix_Stat(filename, dereference,
out device, out inode, out mode, out Int32 device, out Int32 inode, out Int32 mode,
out nlinks, out uid, out gid, out Int32 nlinks, out Int32 uid, out Int32 gid,
out rdev, out size, out blksize, out blocks, out Int32 rdev, out Int64 size, out Int64 blksize, out Int64 blocks,
out atime, out mtime, out ctime); out Int64 atime, out Int64 mtime, out Int64 ctime);
stat = new Stat( stat = new Stat(
device, inode, mode, device, inode, mode,
@ -471,47 +523,54 @@ namespace Mono.Posix {
rdev, size, blksize, blocks, rdev, size, blksize, blocks,
atime, mtime, ctime); atime, mtime, ctime);
if (ret != 0) return ret; if (ret != 0) {
return ret;
}
return 0; return 0;
} }
public static int stat(string filename, out Stat stat) { [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
return stat2(filename, false, out stat); public static Int32 stat(String filename, out Stat stat) => stat2(filename, false, out stat);
}
public static int lstat(string filename, out Stat stat) { [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
return stat2(filename, true, out stat); public static Int32 lstat(String filename, out Stat stat) => stat2(filename, true, out stat);
}
[DllImport ("libc")] [DllImport ("libc")]
private static extern int readlink(string path, byte[] buffer, int buflen); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static extern Int32 readlink(String path, Byte[] buffer, Int32 buflen);
public static string readlink(string path) { [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
byte[] buf = new byte[512]; public static String readlink(String path) {
int ret = readlink(path, buf, buf.Length); Byte[] buf = new Byte[512];
if (ret == -1) return null; Int32 ret = readlink(path, buf, buf.Length);
char[] cbuf = new char[512]; if (ret == -1) {
int chars = System.Text.Encoding.Default.GetChars(buf, 0, ret, cbuf, 0); return null;
}
Char[] cbuf = new Char[512];
Int32 chars = System.Text.Encoding.Default.GetChars(buf, 0, ret, cbuf, 0);
return new String(cbuf, 0, chars); return new String(cbuf, 0, chars);
} }
[DllImport ("libc", EntryPoint="strerror")] [DllImport ("libc", EntryPoint="strerror")]
static extern IntPtr _strerror(int errnum); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr _strerror(Int32 errnum);
public static string strerror (int errnum) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ public static String strerror(Int32 errnum) => Marshal.PtrToStringAnsi(_strerror(errnum));
return Marshal.PtrToStringAnsi (_strerror (errnum));
}
[DllImport ("libc")] [DllImport ("libc")]
public static extern IntPtr opendir(string path); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern IntPtr opendir(String path);
[DllImport ("libc")] [DllImport ("libc")]
public static extern int closedir(IntPtr dir); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern Int32 closedir(IntPtr dir);
[DllImport ("MonoPosixHelper", EntryPoint="helper_Mono_Posix_readdir")] [DllImport ("MonoPosixHelper", EntryPoint="helper_Mono_Posix_readdir")]
public static extern string readdir(IntPtr dir); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
public static extern String readdir(IntPtr dir);
} }
@ -573,25 +632,25 @@ namespace Mono.Posix {
[Obsolete ("Use Mono.Unix.Native.Stat")] [Obsolete ("Use Mono.Unix.Native.Stat")]
public struct Stat { public struct Stat {
[Obsolete ("Use Mono.Unix.Native.Stat.st_dev")] [Obsolete ("Use Mono.Unix.Native.Stat.st_dev")]
public readonly int Device; public readonly Int32 Device;
[Obsolete ("Use Mono.Unix.Native.Stat.st_ino")] [Obsolete ("Use Mono.Unix.Native.Stat.st_ino")]
public readonly int INode; public readonly Int32 INode;
[Obsolete ("Use Mono.Unix.Native.Stat.st_mode")] [Obsolete ("Use Mono.Unix.Native.Stat.st_mode")]
public readonly StatMode Mode; public readonly StatMode Mode;
[Obsolete ("Use Mono.Unix.Native.Stat.st_nlink")] [Obsolete ("Use Mono.Unix.Native.Stat.st_nlink")]
public readonly int NLinks; public readonly Int32 NLinks;
[Obsolete ("Use Mono.Unix.Native.Stat.st_uid")] [Obsolete ("Use Mono.Unix.Native.Stat.st_uid")]
public readonly int Uid; public readonly Int32 Uid;
[Obsolete ("Use Mono.Unix.Native.Stat.st_gid")] [Obsolete ("Use Mono.Unix.Native.Stat.st_gid")]
public readonly int Gid; public readonly Int32 Gid;
[Obsolete ("Use Mono.Unix.Native.Stat.st_rdev")] [Obsolete ("Use Mono.Unix.Native.Stat.st_rdev")]
public readonly long DeviceType; public readonly Int64 DeviceType;
[Obsolete ("Use Mono.Unix.Native.Stat.st_size")] [Obsolete ("Use Mono.Unix.Native.Stat.st_size")]
public readonly long Size; public readonly Int64 Size;
[Obsolete ("Use Mono.Unix.Native.Stat.st_blksize")] [Obsolete ("Use Mono.Unix.Native.Stat.st_blksize")]
public readonly long BlockSize; public readonly Int64 BlockSize;
[Obsolete ("Use Mono.Unix.Native.Stat.st_blocks")] [Obsolete ("Use Mono.Unix.Native.Stat.st_blocks")]
public readonly long Blocks; public readonly Int64 Blocks;
[Obsolete ("Use Mono.Unix.Native.Stat.st_atime")] [Obsolete ("Use Mono.Unix.Native.Stat.st_atime")]
public readonly DateTime ATime; public readonly DateTime ATime;
[Obsolete ("Use Mono.Unix.Native.Stat.st_mtime")] [Obsolete ("Use Mono.Unix.Native.Stat.st_mtime")]
@ -602,38 +661,41 @@ namespace Mono.Posix {
[Obsolete ("Use Mono.Unix.Native.NativeConvert.LocalUnixEpoch")] [Obsolete ("Use Mono.Unix.Native.NativeConvert.LocalUnixEpoch")]
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1); public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
[Obsolete ("Use Mono.Unix.Native.NativeConvert.ToDateTime")] [Obsolete("Use Mono.Unix.Native.NativeConvert.ToDateTime")]
public static DateTime UnixToDateTime(long unix) { public static DateTime UnixToDateTime(Int64 unix) => UnixEpoch.Add(TimeSpan.FromSeconds(unix)).ToLocalTime();
return UnixEpoch.Add(TimeSpan.FromSeconds(unix)).ToLocalTime();
}
internal Stat( internal Stat(
int device, int inode, int mode, Int32 device, Int32 inode, Int32 mode,
int nlinks, int uid, int gid, Int32 nlinks, Int32 uid, Int32 gid,
int rdev, long size, long blksize, long blocks, Int32 rdev, Int64 size, Int64 blksize, Int64 blocks,
long atime, long mtime, long ctime) { Int64 atime, Int64 mtime, Int64 ctime) {
Device = device; this.Device = device;
INode = inode; this.INode = inode;
Mode = (StatMode)mode; this.Mode = (StatMode)mode;
NLinks = nlinks; this.NLinks = nlinks;
Uid = uid; this.Uid = uid;
Gid = gid; this.Gid = gid;
DeviceType = rdev; this.DeviceType = rdev;
Size = size; this.Size = size;
BlockSize = blksize; this.BlockSize = blksize;
Blocks = blocks; this.Blocks = blocks;
if (atime != 0) if (atime != 0) {
ATime = UnixToDateTime(atime); this.ATime = UnixToDateTime(atime);
else } else {
ATime = new DateTime(); this.ATime = new DateTime();
if (mtime != 0) }
MTime = UnixToDateTime(mtime);
else if (mtime != 0) {
MTime = new DateTime(); this.MTime = UnixToDateTime(mtime);
if (ctime != 0) } else {
CTime = UnixToDateTime(ctime); this.MTime = new DateTime();
else }
CTime = new DateTime();
if (ctime != 0) {
this.CTime = UnixToDateTime(ctime);
} else {
this.CTime = new DateTime();
}
} }
} }

View File

@ -38,30 +38,27 @@ namespace Mono.Posix
[Obsolete ("Use Mono.Unix.UnixEndPoint")] [Obsolete ("Use Mono.Unix.UnixEndPoint")]
public class UnixEndPoint : EndPoint public class UnixEndPoint : EndPoint
{ {
string filename; String filename;
public UnixEndPoint (string filename) public UnixEndPoint (String filename)
{ {
if (filename == null) if (filename == null) {
throw new ArgumentNullException ("filename"); throw new ArgumentNullException ("filename");
}
if (filename == "") if (filename == "") {
throw new ArgumentException ("Cannot be empty.", "filename"); throw new ArgumentException ("Cannot be empty.", "filename");
}
this.filename = filename; this.filename = filename;
} }
public string Filename { public String Filename {
get { get => this.filename;
return(filename); set => this.filename = value;
}
set {
filename=value;
}
} }
public override AddressFamily AddressFamily { public override AddressFamily AddressFamily => AddressFamily.Unix;
get { return AddressFamily.Unix; }
}
public override EndPoint Create (SocketAddress socketAddress) public override EndPoint Create (SocketAddress socketAddress)
{ {
@ -76,42 +73,39 @@ namespace Mono.Posix
throw new ArgumentException ("socketAddress is not a unix socket address."); throw new ArgumentException ("socketAddress is not a unix socket address.");
*/ */
byte [] bytes = new byte [socketAddress.Size - 2]; Byte[] bytes = new Byte[socketAddress.Size - 2];
for (int i = 0; i < bytes.Length; i++) { for (Int32 i = 0; i < bytes.Length; i++) {
bytes [i] = socketAddress [i + 2]; bytes [i] = socketAddress [i + 2];
} }
string name = Encoding.Default.GetString (bytes); String name = Encoding.Default.GetString (bytes);
return new UnixEndPoint (name); return new UnixEndPoint (name);
} }
public override SocketAddress Serialize () public override SocketAddress Serialize ()
{ {
byte [] bytes = Encoding.Default.GetBytes (filename); Byte[] bytes = Encoding.Default.GetBytes (this.filename);
SocketAddress sa = new SocketAddress (AddressFamily, bytes.Length + 2); SocketAddress sa = new SocketAddress (this.AddressFamily, bytes.Length + 2);
// sa [0] -> family low byte, sa [1] -> family high byte // sa [0] -> family low byte, sa [1] -> family high byte
for (int i = 0; i < bytes.Length; i++) for (Int32 i = 0; i < bytes.Length; i++) {
sa [i + 2] = bytes [i]; sa [i + 2] = bytes [i];
}
return sa; return sa;
} }
public override string ToString() { public override String ToString() => this.filename;
return(filename);
}
public override int GetHashCode () public override Int32 GetHashCode() => this.filename.GetHashCode();
{
return filename.GetHashCode ();
}
public override bool Equals (object o) public override Boolean Equals (Object o)
{ {
UnixEndPoint other = o as UnixEndPoint; UnixEndPoint other = o as UnixEndPoint;
if (other == null) if (other == null) {
return false; return false;
}
return (other.filename == filename); return other.filename == this.filename;
} }
} }
} }

View File

@ -44,90 +44,70 @@ namespace Mono.Remoting.Channels.Unix
UnixBinaryCore _binaryCore = UnixBinaryCore.DefaultInstance; UnixBinaryCore _binaryCore = UnixBinaryCore.DefaultInstance;
IClientChannelSink _nextInChain; IClientChannelSink _nextInChain;
public UnixBinaryClientFormatterSink (IClientChannelSink nextSink) public UnixBinaryClientFormatterSink(IClientChannelSink nextSink) => this._nextInChain = nextSink;
{
_nextInChain = nextSink; internal UnixBinaryCore BinaryCore {
get => this._binaryCore;
set => this._binaryCore = value;
} }
internal UnixBinaryCore BinaryCore public IClientChannelSink NextChannelSink => this._nextInChain;
{
get { return _binaryCore; }
set { _binaryCore = value; }
}
public IClientChannelSink NextChannelSink public IMessageSink NextSink =>
{
get {
return _nextInChain;
}
}
public IMessageSink NextSink
{
get {
// This is the last sink in the IMessageSink sink chain // This is the last sink in the IMessageSink sink chain
return null; null;
}
}
public IDictionary Properties public IDictionary Properties => null;
{
get {
return null;
}
}
public void AsyncProcessRequest (IClientChannelSinkStack sinkStack, public void AsyncProcessRequest(IClientChannelSinkStack sinkStack,
IMessage msg, IMessage msg,
ITransportHeaders headers, ITransportHeaders headers,
Stream stream) Stream stream) =>
{
// never called because the formatter sink is // never called because the formatter sink is
// always the first in the chain // always the first in the chain
throw new NotSupportedException("UnixBinaryClientFormatterSink must be the first sink in the IClientChannelSink chain"); throw new NotSupportedException("UnixBinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
}
public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack, public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
object state, Object state,
ITransportHeaders headers, ITransportHeaders headers,
Stream stream) Stream stream)
{ {
IMessage replyMessage = (IMessage)_binaryCore.Deserializer.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state); IMessage replyMessage = (IMessage)this._binaryCore.Deserializer.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state);
sinkStack.DispatchReplyMessage (replyMessage); sinkStack.DispatchReplyMessage (replyMessage);
} }
public Stream GetRequestStream (IMessage msg, public Stream GetRequestStream(IMessage msg,
ITransportHeaders headers) ITransportHeaders headers) =>
{
// never called // never called
throw new NotSupportedException (); throw new NotSupportedException();
}
public void ProcessMessage (IMessage msg, public void ProcessMessage(IMessage msg,
ITransportHeaders requestHeaders, ITransportHeaders requestHeaders,
Stream requestStream, Stream requestStream,
out ITransportHeaders responseHeaders, out ITransportHeaders responseHeaders,
out Stream responseStream) out Stream responseStream) =>
{
// never called because the formatter sink is // never called because the formatter sink is
// always the first in the chain // always the first in the chain
throw new NotSupportedException (); throw new NotSupportedException();
}
public IMessageCtrl AsyncProcessMessage (IMessage msg, public IMessageCtrl AsyncProcessMessage (IMessage msg,
IMessageSink replySink) IMessageSink replySink)
{ {
ITransportHeaders transportHeaders = new TransportHeaders(); ITransportHeaders transportHeaders = new TransportHeaders();
Stream stream = _nextInChain.GetRequestStream(msg, transportHeaders); Stream stream = this._nextInChain.GetRequestStream(msg, transportHeaders);
if (stream == null) stream = new MemoryStream (); if (stream == null) {
stream = new MemoryStream ();
}
_binaryCore.Serializer.Serialize (stream, msg, null); this._binaryCore.Serializer.Serialize (stream, msg, null);
if (stream is MemoryStream) stream.Position = 0; if (stream is MemoryStream) {
stream.Position = 0;
}
ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink); ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
stack.Push (this, msg); stack.Push (this, msg);
_nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream); this._nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream);
// FIXME: No idea about how to implement IMessageCtrl // FIXME: No idea about how to implement IMessageCtrl
return null; return null;
@ -141,23 +121,25 @@ namespace Mono.Remoting.Channels.Unix
call_headers["__RequestUri"] = ((IMethodCallMessage)msg).Uri; call_headers["__RequestUri"] = ((IMethodCallMessage)msg).Uri;
call_headers["Content-Type"] = "application/octet-stream"; call_headers["Content-Type"] = "application/octet-stream";
Stream call_stream = _nextInChain.GetRequestStream(msg, call_headers); Stream call_stream = this._nextInChain.GetRequestStream(msg, call_headers);
if (call_stream == null) call_stream = new MemoryStream (); if (call_stream == null) {
call_stream = new MemoryStream ();
}
// Serialize msg to the stream // Serialize msg to the stream
_binaryCore.Serializer.Serialize (call_stream, msg, null); this._binaryCore.Serializer.Serialize (call_stream, msg, null);
if (call_stream is MemoryStream) call_stream.Position = 0; if (call_stream is MemoryStream) {
call_stream.Position = 0;
}
Stream response_stream;
ITransportHeaders response_headers;
_nextInChain.ProcessMessage (msg, call_headers, call_stream, out response_headers, this._nextInChain.ProcessMessage(msg, call_headers, call_stream, out ITransportHeaders response_headers,
out response_stream); out Stream response_stream);
// Deserialize response_stream // Deserialize response_stream
return (IMessage) _binaryCore.Deserializer.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg); return (IMessage)this._binaryCore.Deserializer.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
} catch (Exception e) { } catch (Exception e) {
return new ReturnMessage (e, (IMethodCallMessage)msg); return new ReturnMessage (e, (IMethodCallMessage)msg);

View File

@ -37,42 +37,32 @@ namespace Mono.Remoting.Channels.Unix
{ {
IClientChannelSinkProvider next = null; IClientChannelSinkProvider next = null;
UnixBinaryCore _binaryCore; UnixBinaryCore _binaryCore;
static string[] allowedProperties = new string [] { "includeVersions", "strictBinding" }; static System.String[] allowedProperties = new System.String[] { "includeVersions", "strictBinding" };
public UnixBinaryClientFormatterSinkProvider () public UnixBinaryClientFormatterSinkProvider() => this._binaryCore = UnixBinaryCore.DefaultInstance;
{
_binaryCore = UnixBinaryCore.DefaultInstance;
}
public UnixBinaryClientFormatterSinkProvider (IDictionary properties, public UnixBinaryClientFormatterSinkProvider(IDictionary properties,
ICollection providerData) ICollection providerData) => this._binaryCore = new UnixBinaryCore(this, properties, allowedProperties);
{
_binaryCore = new UnixBinaryCore (this, properties, allowedProperties);
}
public IClientChannelSinkProvider Next public IClientChannelSinkProvider Next {
{ get => this.next;
get {
return next;
}
set { set => this.next = value;
next = value;
}
} }
public IClientChannelSink CreateSink (IChannelSender channel, public IClientChannelSink CreateSink (IChannelSender channel,
string url, System.String url,
object remoteChannelData) System.Object remoteChannelData)
{ {
IClientChannelSink next_sink = null; IClientChannelSink next_sink = null;
UnixBinaryClientFormatterSink result; UnixBinaryClientFormatterSink result;
if (next != null) if (this.next != null) {
next_sink = next.CreateSink (channel, url, remoteChannelData); next_sink = this.next.CreateSink (channel, url, remoteChannelData);
}
result = new UnixBinaryClientFormatterSink (next_sink); result = new UnixBinaryClientFormatterSink (next_sink);
result.BinaryCore = _binaryCore; result.BinaryCore = this._binaryCore;
return result; return result;
} }

View File

@ -35,6 +35,7 @@ using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics.CodeAnalysis;
namespace Mono.Remoting.Channels.Unix namespace Mono.Remoting.Channels.Unix
{ {
@ -42,41 +43,42 @@ namespace Mono.Remoting.Channels.Unix
{ {
BinaryFormatter _serializationFormatter; BinaryFormatter _serializationFormatter;
BinaryFormatter _deserializationFormatter; BinaryFormatter _deserializationFormatter;
bool _includeVersions = true; Boolean _includeVersions = true;
bool _strictBinding = false; Boolean _strictBinding = false;
IDictionary _properties; IDictionary _properties;
public static UnixBinaryCore DefaultInstance = new UnixBinaryCore (); public static UnixBinaryCore DefaultInstance = new UnixBinaryCore ();
public UnixBinaryCore (object owner, IDictionary properties, string[] allowedProperties) public UnixBinaryCore (Object owner, IDictionary properties, String[] allowedProperties)
{ {
_properties = properties; this._properties = properties;
foreach(DictionaryEntry property in properties) foreach(DictionaryEntry property in properties)
{ {
string key = (string) property.Key; String key = (String) property.Key;
if (Array.IndexOf (allowedProperties, key) == -1) if (Array.IndexOf (allowedProperties, key) == -1) {
throw new RemotingException (owner.GetType().Name + " does not recognize '" + key + "' configuration property"); throw new RemotingException (owner.GetType().Name + " does not recognize '" + key + "' configuration property");
}
switch (key) switch (key)
{ {
case "includeVersions": case "includeVersions":
_includeVersions = Convert.ToBoolean (property.Value); this._includeVersions = Convert.ToBoolean (property.Value);
break; break;
case "strictBinding": case "strictBinding":
_strictBinding = Convert.ToBoolean (property.Value); this._strictBinding = Convert.ToBoolean (property.Value);
break; break;
} }
} }
Init (); this.Init ();
} }
public UnixBinaryCore () public UnixBinaryCore ()
{ {
_properties = new Hashtable (); this._properties = new Hashtable ();
Init (); this.Init ();
} }
public void Init () public void Init ()
@ -84,36 +86,27 @@ namespace Mono.Remoting.Channels.Unix
RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector (); RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector ();
StreamingContext context = new StreamingContext (StreamingContextStates.Remoting, null); StreamingContext context = new StreamingContext (StreamingContextStates.Remoting, null);
_serializationFormatter = new BinaryFormatter (surrogateSelector, context); this._serializationFormatter = new BinaryFormatter (surrogateSelector, context);
_deserializationFormatter = new BinaryFormatter (null, context); this._deserializationFormatter = new BinaryFormatter (null, context);
if (!_includeVersions) if (!this._includeVersions)
{ {
_serializationFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple; this._serializationFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
_deserializationFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple; this._deserializationFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
} }
if (!_strictBinding) if (!this._strictBinding)
{ {
_serializationFormatter.Binder = SimpleBinder.Instance; this._serializationFormatter.Binder = SimpleBinder.Instance;
_deserializationFormatter.Binder = SimpleBinder.Instance; this._deserializationFormatter.Binder = SimpleBinder.Instance;
} }
} }
public BinaryFormatter Serializer public BinaryFormatter Serializer => this._serializationFormatter;
{
get { return _serializationFormatter; }
}
public BinaryFormatter Deserializer public BinaryFormatter Deserializer => this._deserializationFormatter;
{
get { return _deserializationFormatter; }
}
public IDictionary Properties public IDictionary Properties => this._properties;
{
get { return _properties; }
}
} }
@ -121,7 +114,8 @@ namespace Mono.Remoting.Channels.Unix
{ {
public static SimpleBinder Instance = new SimpleBinder (); public static SimpleBinder Instance = new SimpleBinder ();
public override Type BindToType (String assemblyName, string typeName) [SuppressMessage("Microsoft.Design", "CS0618", Justification = "Someone do shit")]
public override Type BindToType (String assemblyName, String typeName)
{ {
Assembly asm; Assembly asm;
@ -131,16 +125,24 @@ namespace Mono.Remoting.Channels.Unix
try try
{ {
asm = Assembly.Load (assemblyName); asm = Assembly.Load (assemblyName);
if (asm == null) return null; if (asm == null) {
return null;
}
Type t = asm.GetType (typeName); Type t = asm.GetType (typeName);
if (t != null) return t; if (t != null) {
return t;
}
} }
catch {} catch {}
} }
// Try using the simple name // Try using the simple name
asm = Assembly.LoadWithPartialName (assemblyName); asm = Assembly.LoadWithPartialName (assemblyName);
if (asm == null) return null; if (asm == null) {
return null;
}
return asm.GetType (typeName, true); return asm.GetType (typeName, true);
} }
} }

View File

@ -53,43 +53,38 @@ namespace Mono.Remoting.Channels.Unix {
this.receiver = receiver; this.receiver = receiver;
} }
internal UnixBinaryCore BinaryCore internal UnixBinaryCore BinaryCore {
{ get => this._binaryCore;
get { return _binaryCore; } set => this._binaryCore = value;
set { _binaryCore = value; }
} }
public IServerChannelSink NextChannelSink { public IServerChannelSink NextChannelSink => this.next_sink;
get {
return next_sink;
}
}
public IDictionary Properties { public IDictionary Properties => null;
get {
return null;
}
}
public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state, public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, Object state,
IMessage message, ITransportHeaders headers, Stream stream) IMessage message, ITransportHeaders headers, Stream stream)
{ {
ITransportHeaders responseHeaders = new TransportHeaders(); ITransportHeaders responseHeaders = new TransportHeaders();
if (sinkStack != null) stream = sinkStack.GetResponseStream (message, responseHeaders); if (sinkStack != null) {
if (stream == null) stream = new MemoryStream(); stream = sinkStack.GetResponseStream (message, responseHeaders);
}
_binaryCore.Serializer.Serialize (stream, message, null); if (stream == null) {
if (stream is MemoryStream) stream.Position = 0; stream = new MemoryStream();
}
this._binaryCore.Serializer.Serialize (stream, message, null);
if (stream is MemoryStream) {
stream.Position = 0;
}
sinkStack.AsyncProcessResponse (message, responseHeaders, stream); sinkStack.AsyncProcessResponse (message, responseHeaders, stream);
} }
public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state, public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state,
IMessage msg, ITransportHeaders headers) IMessage msg, ITransportHeaders headers) => null;
{
return null;
}
public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack, public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,
@ -100,15 +95,16 @@ namespace Mono.Remoting.Channels.Unix {
try try
{ {
string url = (string)requestHeaders["__RequestUri"]; String url = (String)requestHeaders["__RequestUri"];
string uri; _ = this.receiver.Parse(url, out String uri);
receiver.Parse (url, out uri); if (uri == null) {
if (uri == null) uri = url; uri = url;
}
MethodCallHeaderHandler mhh = new MethodCallHeaderHandler(uri); MethodCallHeaderHandler mhh = new MethodCallHeaderHandler(uri);
requestMsg = (IMessage) _binaryCore.Deserializer.Deserialize (requestStream, new HeaderHandler(mhh.HandleHeaders)); requestMsg = (IMessage)this._binaryCore.Deserializer.Deserialize (requestStream, new HeaderHandler(mhh.HandleHeaders));
res = next_sink.ProcessMessage (sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream); res = this.next_sink.ProcessMessage (sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -120,26 +116,35 @@ namespace Mono.Remoting.Channels.Unix {
if (res == ServerProcessing.Complete) if (res == ServerProcessing.Complete)
{ {
for (int n=0; n<3; n++) { for (Int32 n =0; n<3; n++) {
responseStream = null; responseStream = null;
responseHeaders = new TransportHeaders(); responseHeaders = new TransportHeaders();
if (sinkStack != null) responseStream = sinkStack.GetResponseStream (responseMsg, responseHeaders); if (sinkStack != null) {
if (responseStream == null) responseStream = new MemoryStream(); responseStream = sinkStack.GetResponseStream (responseMsg, responseHeaders);
}
if (responseStream == null) {
responseStream = new MemoryStream();
}
try { try {
_binaryCore.Serializer.Serialize (responseStream, responseMsg); this._binaryCore.Serializer.Serialize (responseStream, responseMsg);
break; break;
} catch (Exception ex) { } catch (Exception ex) {
if (n == 2) throw ex; if (n == 2) {
else responseMsg = new ReturnMessage (ex, (IMethodCallMessage)requestMsg); throw ex;
} else {
responseMsg = new ReturnMessage (ex, (IMethodCallMessage)requestMsg);
}
} }
} }
if (responseStream is MemoryStream) responseStream.Position = 0; if (responseStream is MemoryStream) {
responseStream.Position = 0;
}
_ = sinkStack.Pop(this);
sinkStack.Pop (this);
} }
return res; return res;
} }
@ -148,16 +153,10 @@ namespace Mono.Remoting.Channels.Unix {
internal class MethodCallHeaderHandler internal class MethodCallHeaderHandler
{ {
string _uri; String _uri;
public MethodCallHeaderHandler (string uri) public MethodCallHeaderHandler(String uri) => this._uri = uri;
{
_uri = uri;
}
public object HandleHeaders (Header[] headers) public Object HandleHeaders(Header[] headers) => this._uri;
{
return _uri;
}
} }
} }

View File

@ -40,27 +40,16 @@ namespace Mono.Remoting.Channels.Unix
IServerChannelSinkProvider next = null; IServerChannelSinkProvider next = null;
UnixBinaryCore _binaryCore; UnixBinaryCore _binaryCore;
internal static string[] AllowedProperties = new string [] { "includeVersions", "strictBinding" }; internal static System.String[] AllowedProperties = new System.String[] { "includeVersions", "strictBinding" };
public UnixBinaryServerFormatterSinkProvider () public UnixBinaryServerFormatterSinkProvider() => this._binaryCore = UnixBinaryCore.DefaultInstance;
{
_binaryCore = UnixBinaryCore.DefaultInstance;
}
public UnixBinaryServerFormatterSinkProvider (IDictionary properties, ICollection providerData) public UnixBinaryServerFormatterSinkProvider(IDictionary properties, ICollection providerData) => this._binaryCore = new UnixBinaryCore(this, properties, AllowedProperties);
{
_binaryCore = new UnixBinaryCore (this, properties, AllowedProperties);
}
public IServerChannelSinkProvider Next public IServerChannelSinkProvider Next {
{ get => this.next;
get {
return next;
}
set { set => this.next = value;
next = value;
}
} }
public IServerChannelSink CreateSink (IChannelReceiver channel) public IServerChannelSink CreateSink (IChannelReceiver channel)
@ -68,12 +57,13 @@ namespace Mono.Remoting.Channels.Unix
IServerChannelSink next_sink = null; IServerChannelSink next_sink = null;
UnixBinaryServerFormatterSink result; UnixBinaryServerFormatterSink result;
if (next != null) if (this.next != null) {
next_sink = next.CreateSink (channel); next_sink = this.next.CreateSink (channel);
}
result = new UnixBinaryServerFormatterSink (next_sink, channel); result = new UnixBinaryServerFormatterSink (next_sink, channel);
result.BinaryCore = _binaryCore; result.BinaryCore = this._binaryCore;
return result; return result;
} }

View File

@ -40,102 +40,107 @@ namespace Mono.Remoting.Channels.Unix
{ {
private UnixClientChannel _clientChannel; private UnixClientChannel _clientChannel;
private UnixServerChannel _serverChannel = null; private UnixServerChannel _serverChannel = null;
private string _name = "unix"; private String _name = "unix";
private int _priority = 1; private Int32 _priority = 1;
public UnixChannel (): this (null) public UnixChannel (): this (null)
{ {
} }
public UnixChannel (string path) public UnixChannel (String path)
{ {
Hashtable ht = new Hashtable(); Hashtable ht = new Hashtable();
ht["path"] = path; ht["path"] = path;
Init(ht, null, null); this.Init(ht, null, null);
} }
void Init (IDictionary properties, IClientChannelSinkProvider clientSink, IServerChannelSinkProvider serverSink) void Init (IDictionary properties, IClientChannelSinkProvider clientSink, IServerChannelSinkProvider serverSink)
{ {
_clientChannel = new UnixClientChannel (properties,clientSink); this._clientChannel = new UnixClientChannel (properties,clientSink);
if(properties["path"] != null) if(properties["path"] != null) {
_serverChannel = new UnixServerChannel(properties, serverSink); this._serverChannel = new UnixServerChannel(properties, serverSink);
}
object val = properties ["name"]; Object val = properties ["name"];
if (val != null) _name = val as string; if (val != null) {
this._name = val as String;
}
val = properties ["priority"]; val = properties ["priority"];
if (val != null) _priority = Convert.ToInt32 (val); if (val != null) {
this._priority = Convert.ToInt32 (val);
}
} }
public UnixChannel (IDictionary properties, public UnixChannel(IDictionary properties,
IClientChannelSinkProvider clientSinkProvider, IClientChannelSinkProvider clientSinkProvider,
IServerChannelSinkProvider serverSinkProvider) IServerChannelSinkProvider serverSinkProvider) => this.Init(properties, clientSinkProvider, serverSinkProvider);
public IMessageSink CreateMessageSink(String url, Object remoteChannelData, out String objectURI) => this._clientChannel.CreateMessageSink(url, remoteChannelData, out objectURI);
public String ChannelName => this._name;
public Int32 ChannelPriority => this._priority;
public void StartListening (Object data)
{ {
Init (properties, clientSinkProvider, serverSinkProvider); if (this._serverChannel != null) {
this._serverChannel.StartListening (data);
}
} }
public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI) public void StopListening (Object data)
{ {
return _clientChannel.CreateMessageSink(url, remoteChannelData, out objectURI); if (this._serverChannel != null) {
this._serverChannel.StopListening(data);
}
} }
public string ChannelName public String[] GetUrlsForUri (String uri)
{ {
get { return _name; } if (this._serverChannel != null) {
return this._serverChannel.GetUrlsForUri(uri);
} else {
return null;
}
} }
public int ChannelPriority public Object ChannelData
{
get { return _priority; }
}
public void StartListening (object data)
{
if (_serverChannel != null) _serverChannel.StartListening (data);
}
public void StopListening (object data)
{
if (_serverChannel != null) _serverChannel.StopListening(data);
}
public string[] GetUrlsForUri (string uri)
{
if (_serverChannel != null) return _serverChannel.GetUrlsForUri(uri);
else return null;
}
public object ChannelData
{ {
get get
{ {
if (_serverChannel != null) return _serverChannel.ChannelData; if (this._serverChannel != null) {
else return null; return this._serverChannel.ChannelData;
} else {
return null;
}
} }
} }
public string Parse (string url, out string objectURI) public String Parse(String url, out String objectURI) => UnixChannel.ParseUnixURL(url, out objectURI);
{
return UnixChannel.ParseUnixURL (url, out objectURI);
}
internal static string ParseUnixURL (string url, out string objectURI) internal static String ParseUnixURL (String url, out String objectURI)
{ {
// format: "unix:///path/to/unix/socket?/path/to/object" // format: "unix:///path/to/unix/socket?/path/to/object"
objectURI = null; objectURI = null;
if (!url.StartsWith ("unix://")) return null; if (!url.StartsWith ("unix://")) {
return null;
}
int i = url.IndexOf ('?'); Int32 i = url.IndexOf ('?');
if (i == -1) return url.Substring (7); if (i == -1) {
return url.Substring (7);
}
objectURI = url.Substring (i+1); objectURI = url.Substring (i+1);
if (objectURI.Length == 0) if (objectURI.Length == 0) {
objectURI = null; objectURI = null;
}
return url.Substring (7, i - 7); return url.Substring (7, i - 7);
} }

View File

@ -40,31 +40,38 @@ namespace Mono.Remoting.Channels.Unix
{ {
public class UnixClientChannel : IChannelSender, IChannel public class UnixClientChannel : IChannelSender, IChannel
{ {
int priority = 1; Int32 priority = 1;
string name = "unix"; String name = "unix";
IClientChannelSinkProvider _sinkProvider; IClientChannelSinkProvider _sinkProvider;
public UnixClientChannel () public UnixClientChannel ()
{ {
_sinkProvider = new UnixBinaryClientFormatterSinkProvider (); this._sinkProvider = new UnixBinaryClientFormatterSinkProvider ();
_sinkProvider.Next = new UnixClientTransportSinkProvider (); this._sinkProvider.Next = new UnixClientTransportSinkProvider ();
} }
public UnixClientChannel (IDictionary properties, IClientChannelSinkProvider sinkProvider) public UnixClientChannel (IDictionary properties, IClientChannelSinkProvider sinkProvider)
{ {
object val = properties ["name"]; Object val = properties ["name"];
if (val != null) name = val as string; if (val != null) {
this.name = val as String;
}
val = properties ["priority"]; val = properties ["priority"];
if (val != null) priority = Convert.ToInt32 (val); if (val != null) {
this.priority = Convert.ToInt32 (val);
}
if (sinkProvider != null) if (sinkProvider != null)
{ {
_sinkProvider = sinkProvider; this._sinkProvider = sinkProvider;
// add the unix provider at the end of the chain // add the unix provider at the end of the chain
IClientChannelSinkProvider prov = sinkProvider; IClientChannelSinkProvider prov = sinkProvider;
while (prov.Next != null) prov = prov.Next; while (prov.Next != null) {
prov = prov.Next;
}
prov.Next = new UnixClientTransportSinkProvider (); prov.Next = new UnixClientTransportSinkProvider ();
// Note: a default formatter is added only when // Note: a default formatter is added only when
@ -72,63 +79,55 @@ namespace Mono.Remoting.Channels.Unix
} }
else else
{ {
_sinkProvider = new UnixBinaryClientFormatterSinkProvider (); this._sinkProvider = new UnixBinaryClientFormatterSinkProvider ();
_sinkProvider.Next = new UnixClientTransportSinkProvider (); this._sinkProvider.Next = new UnixClientTransportSinkProvider ();
} }
} }
public UnixClientChannel (string name, IClientChannelSinkProvider sinkProvider) public UnixClientChannel (String name, IClientChannelSinkProvider sinkProvider)
{ {
this.name = name; this.name = name;
_sinkProvider = sinkProvider; this._sinkProvider = sinkProvider;
// add the unix provider at the end of the chain // add the unix provider at the end of the chain
IClientChannelSinkProvider prov = sinkProvider; IClientChannelSinkProvider prov = sinkProvider;
while (prov.Next != null) prov = prov.Next; while (prov.Next != null) {
prov = prov.Next;
}
prov.Next = new UnixClientTransportSinkProvider (); prov.Next = new UnixClientTransportSinkProvider ();
} }
public string ChannelName public String ChannelName => this.name;
{
get {
return name;
}
}
public int ChannelPriority public Int32 ChannelPriority => this.priority;
{
get {
return priority;
}
}
public IMessageSink CreateMessageSink (string url, public IMessageSink CreateMessageSink (String url,
object remoteChannelData, Object remoteChannelData,
out string objectURI) out String objectURI)
{ {
if (url != null && Parse (url, out objectURI) != null) if (url != null && this.Parse (url, out objectURI) != null) {
return (IMessageSink) _sinkProvider.CreateSink (this, url, remoteChannelData); return (IMessageSink)this._sinkProvider.CreateSink (this, url, remoteChannelData);
}
if (remoteChannelData != null) { if (remoteChannelData != null) {
IChannelDataStore ds = remoteChannelData as IChannelDataStore; IChannelDataStore ds = remoteChannelData as IChannelDataStore;
if (ds != null && ds.ChannelUris.Length > 0) if (ds != null && ds.ChannelUris.Length > 0) {
url = ds.ChannelUris [0]; url = ds.ChannelUris [0];
else { } else {
objectURI = null; objectURI = null;
return null; return null;
} }
} }
if (Parse (url, out objectURI) == null) if (this.Parse (url, out objectURI) == null) {
return null; return null;
return (IMessageSink) _sinkProvider.CreateSink (this, url, remoteChannelData);
} }
public string Parse (string url, out string objectURI) return (IMessageSink)this._sinkProvider.CreateSink (this, url, remoteChannelData);
{
return UnixChannel.ParseUnixURL (url, out objectURI);
} }
public String Parse(String url, out String objectURI) => UnixChannel.ParseUnixURL(url, out objectURI);
} }
} }

View File

@ -40,70 +40,67 @@ namespace Mono.Remoting.Channels.Unix
{ {
internal class UnixClientTransportSink : IClientChannelSink internal class UnixClientTransportSink : IClientChannelSink
{ {
string _path; String _path;
public UnixClientTransportSink (string url) public UnixClientTransportSink (String url)
{ {
string objectUri; this._path = UnixChannel.ParseUnixURL(url, out String objectUri);
_path = UnixChannel.ParseUnixURL (url, out objectUri);
} }
public IDictionary Properties public IDictionary Properties => null;
{
get
{
return null;
}
}
public IClientChannelSink NextChannelSink public IClientChannelSink NextChannelSink =>
{
get
{
// we are the last one // we are the last one
return null; null;
}
}
public void AsyncProcessRequest (IClientChannelSinkStack sinkStack, IMessage msg, public void AsyncProcessRequest (IClientChannelSinkStack sinkStack, IMessage msg,
ITransportHeaders headers, Stream requestStream) ITransportHeaders headers, Stream requestStream)
{ {
UnixConnection connection = null; UnixConnection connection = null;
bool isOneWay = RemotingServices.IsOneWay (((IMethodMessage)msg).MethodBase); Boolean isOneWay = RemotingServices.IsOneWay (((IMethodMessage)msg).MethodBase);
try try
{ {
if (headers == null) headers = new TransportHeaders(); if (headers == null) {
headers = new TransportHeaders();
}
headers ["__RequestUri"] = ((IMethodMessage)msg).Uri; headers ["__RequestUri"] = ((IMethodMessage)msg).Uri;
// Sends the stream using a connection from the pool // Sends the stream using a connection from the pool
// and creates a WorkItem that will wait for the // and creates a WorkItem that will wait for the
// response of the server // response of the server
connection = UnixConnectionPool.GetConnection (_path); connection = UnixConnectionPool.GetConnection (this._path);
UnixMessageIO.SendMessageStream (connection.Stream, requestStream, headers, connection.Buffer); UnixMessageIO.SendMessageStream (connection.Stream, requestStream, headers, connection.Buffer);
connection.Stream.Flush (); connection.Stream.Flush ();
if (!isOneWay) if (!isOneWay)
{ {
sinkStack.Push (this, connection); sinkStack.Push (this, connection);
ThreadPool.QueueUserWorkItem (new WaitCallback(data => { _ = ThreadPool.QueueUserWorkItem(new WaitCallback(data => {
try { try {
ReadAsyncUnixMessage (data); this.ReadAsyncUnixMessage(data);
} catch {} } catch { }
}), sinkStack); }), sinkStack);
} }
else else {
connection.Release(); connection.Release();
} }
}
catch catch
{ {
if (connection != null) connection.Release(); if (connection != null) {
if (!isOneWay) throw; connection.Release();
}
if (!isOneWay) {
throw;
}
} }
} }
private void ReadAsyncUnixMessage(object data) private void ReadAsyncUnixMessage(Object data)
{ {
// This method is called by a new thread to asynchronously // This method is called by a new thread to asynchronously
// read the response to a request // read the response to a request
@ -118,15 +115,15 @@ namespace Mono.Remoting.Channels.Unix
try try
{ {
ITransportHeaders responseHeaders;
// Read the response, blocking if necessary // Read the response, blocking if necessary
MessageStatus status = UnixMessageIO.ReceiveMessageStatus (connection.Stream, connection.Buffer); MessageStatus status = UnixMessageIO.ReceiveMessageStatus(connection.Stream, connection.Buffer);
if (status != MessageStatus.MethodMessage) if (status != MessageStatus.MethodMessage) {
throw new RemotingException ("Unknown response message from server"); throw new RemotingException ("Unknown response message from server");
}
Stream responseStream = UnixMessageIO.ReceiveMessageStream (connection.Stream, out responseHeaders, connection.Buffer); Stream responseStream = UnixMessageIO.ReceiveMessageStream (connection.Stream, out ITransportHeaders responseHeaders, connection.Buffer);
// Free the connection, so it can be reused // Free the connection, so it can be reused
connection.Release(); connection.Release();
@ -137,23 +134,21 @@ namespace Mono.Remoting.Channels.Unix
} }
catch catch
{ {
if (connection != null) connection.Release(); if (connection != null) {
connection.Release();
}
throw; throw;
} }
} }
public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack, public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack,
object state, ITransportHeaders headers, Object state, ITransportHeaders headers,
Stream stream) Stream stream) =>
{
// Should never be called // Should never be called
throw new NotSupportedException(); throw new NotSupportedException();
}
public Stream GetRequestStream (IMessage msg, ITransportHeaders headers) public Stream GetRequestStream(IMessage msg, ITransportHeaders headers) => null;
{
return null;
}
public void ProcessMessage (IMessage msg, public void ProcessMessage (IMessage msg,
ITransportHeaders requestHeaders, ITransportHeaders requestHeaders,
@ -164,28 +159,33 @@ namespace Mono.Remoting.Channels.Unix
UnixConnection connection = null; UnixConnection connection = null;
try try
{ {
if (requestHeaders == null) requestHeaders = new TransportHeaders(); if (requestHeaders == null) {
requestHeaders = new TransportHeaders();
}
requestHeaders ["__RequestUri"] = ((IMethodMessage)msg).Uri; requestHeaders ["__RequestUri"] = ((IMethodMessage)msg).Uri;
// Sends the message // Sends the message
connection = UnixConnectionPool.GetConnection (_path); connection = UnixConnectionPool.GetConnection (this._path);
UnixMessageIO.SendMessageStream (connection.Stream, requestStream, requestHeaders, connection.Buffer); UnixMessageIO.SendMessageStream (connection.Stream, requestStream, requestHeaders, connection.Buffer);
connection.Stream.Flush (); connection.Stream.Flush ();
// Reads the response // Reads the response
MessageStatus status = UnixMessageIO.ReceiveMessageStatus (connection.Stream, connection.Buffer); MessageStatus status = UnixMessageIO.ReceiveMessageStatus (connection.Stream, connection.Buffer);
if (status != MessageStatus.MethodMessage) if (status != MessageStatus.MethodMessage) {
throw new RemotingException ("Unknown response message from server"); throw new RemotingException ("Unknown response message from server");
}
responseStream = UnixMessageIO.ReceiveMessageStream (connection.Stream, out responseHeaders, connection.Buffer); responseStream = UnixMessageIO.ReceiveMessageStream (connection.Stream, out responseHeaders, connection.Buffer);
} }
finally finally
{ {
if (connection != null) if (connection != null) {
connection.Release(); connection.Release();
} }
} }
}
} }

View File

@ -40,23 +40,15 @@ namespace Mono.Remoting.Channels.Unix
// what should we do here ? // what should we do here ?
} }
public IClientChannelSinkProvider Next public IClientChannelSinkProvider Next {
{ get => null;
get
{
return null;
}
set set {
{
// ignore, we are always the last in the chain // ignore, we are always the last in the chain
} }
} }
public IClientChannelSink CreateSink (IChannelSender channel, string url, public IClientChannelSink CreateSink(IChannelSender channel, String url,
object remoteChannelData) Object remoteChannelData) => new UnixClientTransportSink(url);
{
return new UnixClientTransportSink (url);
}
} }
} }

View File

@ -52,8 +52,8 @@ namespace Mono.Remoting.Channels.Unix
// instance for each host // instance for each host
static Hashtable _pools = new Hashtable(); static Hashtable _pools = new Hashtable();
static int _maxOpenConnections = int.MaxValue; static Int32 _maxOpenConnections = Int32.MaxValue;
static int _keepAliveSeconds = 15; static Int32 _keepAliveSeconds = 15;
static Thread _poolThread; static Thread _poolThread;
@ -67,27 +67,28 @@ namespace Mono.Remoting.Channels.Unix
public static void Shutdown () public static void Shutdown ()
{ {
if (_poolThread != null) if (_poolThread != null) {
_poolThread.Abort(); _poolThread.Abort();
} }
}
public static Int32 MaxOpenConnections {
get => _maxOpenConnections;
set {
if(value < 1) {
throw new RemotingException("MaxOpenConnections must be greater than zero");
}
public static int MaxOpenConnections
{
get { return _maxOpenConnections; }
set
{
if (value < 1) throw new RemotingException ("MaxOpenConnections must be greater than zero");
_maxOpenConnections = value; _maxOpenConnections = value;
} }
} }
public static int KeepAliveSeconds public static Int32 KeepAliveSeconds {
{ get => _keepAliveSeconds;
get { return _keepAliveSeconds; } set => _keepAliveSeconds = value;
set { _keepAliveSeconds = value; }
} }
public static UnixConnection GetConnection (string path) public static UnixConnection GetConnection (String path)
{ {
HostConnectionPool hostPool; HostConnectionPool hostPool;
@ -112,32 +113,28 @@ namespace Mono.Remoting.Channels.Unix
lock (_pools) lock (_pools)
{ {
ICollection values = _pools.Values; ICollection values = _pools.Values;
foreach (HostConnectionPool pool in values) foreach (HostConnectionPool pool in values) {
pool.PurgeConnections(); pool.PurgeConnections();
} }
} }
} }
} }
}
internal class ReusableUnixClient : UnixClient internal class ReusableUnixClient : UnixClient
{ {
public ReusableUnixClient (string path): base (path) public ReusableUnixClient (String path): base (path)
{ {
} }
public bool IsAlive public Boolean IsAlive =>
{
get
{
// This Poll will return true if there is data pending to // This Poll will return true if there is data pending to
// be read. It prob. means that a client object using this // be read. It prob. means that a client object using this
// connection got an exception and did not finish to read // connection got an exception and did not finish to read
// the data. It can also mean that the connection has been // the data. It can also mean that the connection has been
// closed in the server. In both cases, the connection cannot // closed in the server. In both cases, the connection cannot
// be reused. // be reused.
return !Client.Poll (0, SelectMode.SelectRead); !this.Client.Poll(0, SelectMode.SelectRead);
}
}
} }
internal class UnixConnection internal class UnixConnection
@ -146,87 +143,68 @@ namespace Mono.Remoting.Channels.Unix
Stream _stream; Stream _stream;
ReusableUnixClient _client; ReusableUnixClient _client;
HostConnectionPool _pool; HostConnectionPool _pool;
byte[] _buffer; Byte[] _buffer;
public UnixConnection (HostConnectionPool pool, ReusableUnixClient client) public UnixConnection (HostConnectionPool pool, ReusableUnixClient client)
{ {
_pool = pool; this._pool = pool;
_client = client; this._client = client;
_stream = new BufferedStream (client.GetStream()); this._stream = new BufferedStream (client.GetStream());
_controlTime = DateTime.UtcNow; this._controlTime = DateTime.UtcNow;
_buffer = new byte[UnixMessageIO.DefaultStreamBufferSize]; this._buffer = new Byte[UnixMessageIO.DefaultStreamBufferSize];
} }
public Stream Stream public Stream Stream => this._stream;
{
get { return _stream; } public DateTime ControlTime {
get => this._controlTime;
set => this._controlTime = value;
} }
public DateTime ControlTime public Boolean IsAlive => this._client.IsAlive;
{
get { return _controlTime; }
set { _controlTime = value; }
}
public bool IsAlive
{
get { return _client.IsAlive; }
}
// This is a "thread safe" buffer that can be used by // This is a "thread safe" buffer that can be used by
// UnixClientTransportSink to read or send data to the stream. // UnixClientTransportSink to read or send data to the stream.
// The buffer is "thread safe" since only one thread can // The buffer is "thread safe" since only one thread can
// use a connection at a given time. // use a connection at a given time.
public byte[] Buffer public Byte[] Buffer => this._buffer;
{
get { return _buffer; }
}
// Returns the connection to the pool // Returns the connection to the pool
public void Release() public void Release() => this._pool.ReleaseConnection(this);
{
_pool.ReleaseConnection (this);
}
public void Close() public void Close() => this._client.Close();
{
_client.Close();
}
} }
internal class HostConnectionPool internal class HostConnectionPool
{ {
ArrayList _pool = new ArrayList(); ArrayList _pool = new ArrayList();
int _activeConnections = 0; Int32 _activeConnections = 0;
string _path; String _path;
public HostConnectionPool (string path) public HostConnectionPool(String path) => this._path = path;
{
_path = path;
}
public UnixConnection GetConnection () public UnixConnection GetConnection ()
{ {
UnixConnection connection = null; UnixConnection connection = null;
lock (_pool) lock (this._pool)
{ {
do do
{ {
if (_pool.Count > 0) if (this._pool.Count > 0)
{ {
// There are available connections // There are available connections
connection = (UnixConnection)_pool[_pool.Count - 1]; connection = (UnixConnection)this._pool[this._pool.Count - 1];
_pool.RemoveAt(_pool.Count - 1); this._pool.RemoveAt(this._pool.Count - 1);
if (!connection.IsAlive) { if (!connection.IsAlive) {
CancelConnection (connection); this.CancelConnection (connection);
connection = null; connection = null;
continue; continue;
} }
} }
if (connection == null && _activeConnections < UnixConnectionPool.MaxOpenConnections) if (connection == null && this._activeConnections < UnixConnectionPool.MaxOpenConnections)
{ {
// No connections available, but the max connections // No connections available, but the max connections
// has not been reached yet, so a new one can be created // has not been reached yet, so a new one can be created
@ -239,25 +217,26 @@ namespace Mono.Remoting.Channels.Unix
if (connection == null) if (connection == null)
{ {
Monitor.Wait(_pool); _ = Monitor.Wait(this._pool);
} }
} }
while (connection == null); while (connection == null);
} }
if (connection == null) if (connection == null) {
return CreateConnection (); return this.CreateConnection ();
else } else {
return connection; return connection;
} }
}
private UnixConnection CreateConnection() private UnixConnection CreateConnection()
{ {
try try
{ {
ReusableUnixClient client = new ReusableUnixClient (_path); ReusableUnixClient client = new ReusableUnixClient (this._path);
UnixConnection entry = new UnixConnection(this, client); UnixConnection entry = new UnixConnection(this, client);
_activeConnections++; this._activeConnections++;
return entry; return entry;
} }
catch (Exception ex) catch (Exception ex)
@ -268,11 +247,11 @@ namespace Mono.Remoting.Channels.Unix
public void ReleaseConnection (UnixConnection entry) public void ReleaseConnection (UnixConnection entry)
{ {
lock (_pool) lock (this._pool)
{ {
entry.ControlTime = DateTime.UtcNow; // Initialize timeout entry.ControlTime = DateTime.UtcNow; // Initialize timeout
_pool.Add (entry); _ = this._pool.Add(entry);
Monitor.Pulse (_pool); Monitor.Pulse (this._pool);
} }
} }
@ -281,7 +260,7 @@ namespace Mono.Remoting.Channels.Unix
try try
{ {
entry.Stream.Close(); entry.Stream.Close();
_activeConnections--; this._activeConnections--;
} }
catch catch
{ {
@ -290,15 +269,15 @@ namespace Mono.Remoting.Channels.Unix
public void PurgeConnections() public void PurgeConnections()
{ {
lock (_pool) lock (this._pool)
{ {
for (int n=0; n < _pool.Count; n++) for (Int32 n =0; n < this._pool.Count; n++)
{ {
UnixConnection entry = (UnixConnection)_pool[n]; UnixConnection entry = (UnixConnection)this._pool[n];
if ( (DateTime.UtcNow - entry.ControlTime).TotalSeconds > UnixConnectionPool.KeepAliveSeconds) if ( (DateTime.UtcNow - entry.ControlTime).TotalSeconds > UnixConnectionPool.KeepAliveSeconds)
{ {
CancelConnection (entry); this.CancelConnection (entry);
_pool.RemoveAt(n); this._pool.RemoveAt(n);
n--; n--;
} }
} }

View File

@ -42,39 +42,44 @@ namespace Mono.Remoting.Channels.Unix
internal class UnixMessageIO internal class UnixMessageIO
{ {
static byte[][] _msgHeaders = static Byte[][] _msgHeaders =
{ {
new byte[] { (byte)'.', (byte)'N', (byte)'E', (byte)'T', 1, 0 }, new Byte[] { (Byte)'.', (Byte)'N', (Byte)'E', (Byte)'T', 1, 0 },
new byte[] { 255, 255, 255, 255, 255, 255 } new Byte[] { 255, 255, 255, 255, 255, 255 }
}; };
public static int DefaultStreamBufferSize = 1000; public static Int32 DefaultStreamBufferSize = 1000;
// Identifies an incoming message // Identifies an incoming message
public static MessageStatus ReceiveMessageStatus (Stream networkStream, byte[] buffer) public static MessageStatus ReceiveMessageStatus (Stream networkStream, Byte[] buffer)
{ {
try { try {
StreamRead (networkStream, buffer, 6); _ = StreamRead(networkStream, buffer, 6);
} catch (Exception ex) { } catch (Exception ex) {
throw new RemotingException ("Unix transport error.", ex); throw new RemotingException ("Unix transport error.", ex);
} }
try try
{ {
bool[] isOnTrack = new bool[_msgHeaders.Length]; Boolean[] isOnTrack = new Boolean[_msgHeaders.Length];
bool atLeastOneOnTrack = true; Boolean atLeastOneOnTrack = true;
int i = 0; Int32 i = 0;
while (atLeastOneOnTrack) while (atLeastOneOnTrack)
{ {
atLeastOneOnTrack = false; atLeastOneOnTrack = false;
byte c = buffer [i]; Byte c = buffer [i];
for (int n = 0; n<_msgHeaders.Length; n++) for (Int32 n = 0; n<_msgHeaders.Length; n++)
{ {
if (i > 0 && !isOnTrack[n]) continue; if (i > 0 && !isOnTrack[n]) {
continue;
}
isOnTrack[n] = c == _msgHeaders[n][i];
if (isOnTrack[n] && i == _msgHeaders[n].Length-1) {
return (MessageStatus) n;
}
isOnTrack[n] = (c == _msgHeaders[n][i]);
if (isOnTrack[n] && (i == _msgHeaders[n].Length-1)) return (MessageStatus) n;
atLeastOneOnTrack = atLeastOneOnTrack || isOnTrack[n]; atLeastOneOnTrack = atLeastOneOnTrack || isOnTrack[n];
} }
i++; i++;
@ -86,43 +91,51 @@ namespace Mono.Remoting.Channels.Unix
} }
} }
static bool StreamRead (Stream networkStream, byte[] buffer, int count) static Boolean StreamRead (Stream networkStream, Byte[] buffer, Int32 count)
{ {
int nr = 0; Int32 nr = 0;
do { do {
int pr = networkStream.Read (buffer, nr, count - nr); Int32 pr = networkStream.Read (buffer, nr, count - nr);
if (pr == 0) if (pr == 0) {
throw new RemotingException ("Connection closed"); throw new RemotingException ("Connection closed");
}
nr += pr; nr += pr;
} while (nr < count); } while (nr < count);
return true; return true;
} }
public static void SendMessageStream (Stream networkStream, Stream data, ITransportHeaders requestHeaders, byte[] buffer) public static void SendMessageStream (Stream networkStream, Stream data, ITransportHeaders requestHeaders, Byte[] buffer)
{ {
if (buffer == null) buffer = new byte[DefaultStreamBufferSize]; if (buffer == null) {
buffer = new Byte[DefaultStreamBufferSize];
}
// Writes the message start header // Writes the message start header
byte[] dotnetHeader = _msgHeaders[(int) MessageStatus.MethodMessage]; Byte[] dotnetHeader = _msgHeaders[(Int32) MessageStatus.MethodMessage];
networkStream.Write(dotnetHeader, 0, dotnetHeader.Length); networkStream.Write(dotnetHeader, 0, dotnetHeader.Length);
// Writes header tag (0x0000 if request stream, 0x0002 if response stream) // Writes header tag (0x0000 if request stream, 0x0002 if response stream)
if(requestHeaders["__RequestUri"]!=null) buffer [0] = (byte) 0; if(requestHeaders["__RequestUri"]!=null) {
else buffer[0] = (byte) 2; buffer [0] = (Byte) 0;
buffer [1] = (byte) 0 ; } else {
buffer[0] = (Byte) 2;
}
buffer [1] = (Byte) 0 ;
// Writes ID // Writes ID
buffer [2] = (byte) 0; buffer [2] = (Byte) 0;
// Writes assemblyID???? // Writes assemblyID????
buffer [3] = (byte) 0; buffer [3] = (Byte) 0;
// Writes the length of the stream being sent (not including the headers) // Writes the length of the stream being sent (not including the headers)
int num = (int)data.Length; Int32 num = (Int32)data.Length;
buffer [4] = (byte) num; buffer [4] = (Byte) num;
buffer [5] = (byte) (num >> 8); buffer [5] = (Byte) (num >> 8);
buffer [6] = (byte) (num >> 16); buffer [6] = (Byte) (num >> 16);
buffer [7] = (byte) (num >> 24); buffer [7] = (Byte) (num >> 24);
networkStream.Write(buffer, 0, 8); networkStream.Write(buffer, 0, 8);
// Writes the message headers // Writes the message headers
@ -134,11 +147,11 @@ namespace Mono.Remoting.Channels.Unix
// The copy of the stream can be optimized. The internal // The copy of the stream can be optimized. The internal
// buffer of MemoryStream can be used. // buffer of MemoryStream can be used.
MemoryStream memStream = (MemoryStream)data; MemoryStream memStream = (MemoryStream)data;
networkStream.Write (memStream.GetBuffer(), 0, (int)memStream.Length); networkStream.Write (memStream.GetBuffer(), 0, (Int32)memStream.Length);
} }
else else
{ {
int nread = data.Read (buffer, 0, buffer.Length); Int32 nread = data.Read (buffer, 0, buffer.Length);
while (nread > 0) while (nread > 0)
{ {
networkStream.Write (buffer, 0, nread); networkStream.Write (buffer, 0, nread);
@ -147,12 +160,12 @@ namespace Mono.Remoting.Channels.Unix
} }
} }
static byte[] msgUriTransportKey = new byte[] { 4, 0, 1, 1 }; static Byte[] msgUriTransportKey = new Byte[] { 4, 0, 1, 1 };
static byte[] msgContentTypeTransportKey = new byte[] { 6, 0, 1, 1 }; static Byte[] msgContentTypeTransportKey = new Byte[] { 6, 0, 1, 1 };
static byte[] msgDefaultTransportKey = new byte[] { 1, 0, 1 }; static Byte[] msgDefaultTransportKey = new Byte[] { 1, 0, 1 };
static byte[] msgHeaderTerminator = new byte[] { 0, 0 }; static Byte[] msgHeaderTerminator = new Byte[] { 0, 0 };
private static void SendHeaders(Stream networkStream, ITransportHeaders requestHeaders, byte[] buffer) private static void SendHeaders(Stream networkStream, ITransportHeaders requestHeaders, Byte[] buffer)
{ {
// Writes the headers as a sequence of strings // Writes the headers as a sequence of strings
if (networkStream != null) if (networkStream != null)
@ -181,17 +194,17 @@ namespace Mono.Remoting.Channels.Unix
networkStream.Write (msgHeaderTerminator, 0, 2); // End of headers networkStream.Write (msgHeaderTerminator, 0, 2); // End of headers
} }
public static ITransportHeaders ReceiveHeaders (Stream networkStream, byte[] buffer) public static ITransportHeaders ReceiveHeaders (Stream networkStream, Byte[] buffer)
{ {
StreamRead (networkStream, buffer, 2); _ = StreamRead(networkStream, buffer, 2);
byte headerType = buffer [0]; Byte headerType = buffer [0];
TransportHeaders headers = new TransportHeaders (); TransportHeaders headers = new TransportHeaders ();
while (headerType != 0) while (headerType != 0)
{ {
string key; String key;
StreamRead (networkStream, buffer, 1); // byte 1 _ = StreamRead(networkStream, buffer, 1); // byte 1
switch (headerType) switch (headerType)
{ {
case 4: key = "__RequestUri"; break; case 4: key = "__RequestUri"; break;
@ -199,84 +212,90 @@ namespace Mono.Remoting.Channels.Unix
case 1: key = ReceiveString (networkStream, buffer); break; case 1: key = ReceiveString (networkStream, buffer); break;
default: throw new NotSupportedException ("Unknown header code: " + headerType); default: throw new NotSupportedException ("Unknown header code: " + headerType);
} }
StreamRead (networkStream, buffer, 1); // byte 1 _ = StreamRead(networkStream, buffer, 1); // byte 1
headers[key] = ReceiveString (networkStream, buffer); headers[key] = ReceiveString (networkStream, buffer);
StreamRead (networkStream, buffer, 2); _ = StreamRead(networkStream, buffer, 2);
headerType = buffer [0]; headerType = buffer [0];
} }
return headers; return headers;
} }
public static Stream ReceiveMessageStream (Stream networkStream, out ITransportHeaders headers, byte[] buffer) public static Stream ReceiveMessageStream (Stream networkStream, out ITransportHeaders headers, Byte[] buffer)
{ {
headers = null; headers = null;
if (buffer == null) buffer = new byte[DefaultStreamBufferSize]; if (buffer == null) {
buffer = new Byte[DefaultStreamBufferSize];
}
// Reads header tag: 0 -> Stream with headers or 2 -> Response Stream // Reads header tag: 0 -> Stream with headers or 2 -> Response Stream
// + // +
// Gets the length of the data stream // Gets the length of the data stream
StreamRead (networkStream, buffer, 8); _ = StreamRead(networkStream, buffer, 8);
int byteCount = (buffer [4] | (buffer [5] << 8) | Int32 byteCount = buffer [4] | (buffer [5] << 8) |
(buffer [6] << 16) | (buffer [7] << 24)); (buffer [6] << 16) | (buffer [7] << 24);
// Reads the headers // Reads the headers
headers = ReceiveHeaders (networkStream, buffer); headers = ReceiveHeaders (networkStream, buffer);
byte[] resultBuffer = new byte[byteCount]; Byte[] resultBuffer = new Byte[byteCount];
StreamRead (networkStream, resultBuffer, byteCount); _ = StreamRead(networkStream, resultBuffer, byteCount);
return new MemoryStream (resultBuffer); return new MemoryStream (resultBuffer);
} }
private static void SendString (Stream networkStream, string str, byte[] buffer) private static void SendString (Stream networkStream, String str, Byte[] buffer)
{ {
// Allocates a buffer. Use the internal buffer if it is // Allocates a buffer. Use the internal buffer if it is
// big enough. If not, create a new one. // big enough. If not, create a new one.
int maxBytes = Encoding.UTF8.GetMaxByteCount(str.Length)+4; //+4 bytes for storing the string length Int32 maxBytes = Encoding.UTF8.GetMaxByteCount(str.Length)+4; //+4 bytes for storing the string length
if (maxBytes > buffer.Length) if (maxBytes > buffer.Length) {
buffer = new byte[maxBytes]; buffer = new Byte[maxBytes];
}
int num = Encoding.UTF8.GetBytes (str, 0, str.Length, buffer, 4); Int32 num = Encoding.UTF8.GetBytes (str, 0, str.Length, buffer, 4);
// store number of bytes (not number of chars!) // store number of bytes (not number of chars!)
buffer [0] = (byte) num; buffer [0] = (Byte) num;
buffer [1] = (byte) (num >> 8); buffer [1] = (Byte) (num >> 8);
buffer [2] = (byte) (num >> 16); buffer [2] = (Byte) (num >> 16);
buffer [3] = (byte) (num >> 24); buffer [3] = (Byte) (num >> 24);
// Write the string bytes // Write the string bytes
networkStream.Write (buffer, 0, num + 4); networkStream.Write (buffer, 0, num + 4);
} }
private static string ReceiveString (Stream networkStream, byte[] buffer) private static String ReceiveString (Stream networkStream, Byte[] buffer)
{ {
StreamRead (networkStream, buffer, 4); _ = StreamRead(networkStream, buffer, 4);
// Reads the number of bytes (not chars!) // Reads the number of bytes (not chars!)
int byteCount = (buffer [0] | (buffer [1] << 8) | Int32 byteCount = buffer [0] | (buffer [1] << 8) |
(buffer [2] << 16) | (buffer [3] << 24)); (buffer [2] << 16) | (buffer [3] << 24);
if (byteCount == 0) return string.Empty; if (byteCount == 0) {
return String.Empty;
}
// Allocates a buffer of the correct size. Use the // Allocates a buffer of the correct size. Use the
// internal buffer if it is big enough // internal buffer if it is big enough
if (byteCount > buffer.Length) if (byteCount > buffer.Length) {
buffer = new byte[byteCount]; buffer = new Byte[byteCount];
}
// Reads the string // Reads the string
StreamRead (networkStream, buffer, byteCount); _ = StreamRead(networkStream, buffer, byteCount);
char[] chars = Encoding.UTF8.GetChars (buffer, 0, byteCount); Char[] chars = Encoding.UTF8.GetChars (buffer, 0, byteCount);
return new string (chars); return new String(chars);
} }
} }

View File

@ -43,17 +43,17 @@ namespace Mono.Remoting.Channels.Unix
{ {
public class UnixServerChannel : IChannelReceiver, IChannel public class UnixServerChannel : IChannelReceiver, IChannel
{ {
string path = null; String path = null;
string name = "unix"; String name = "unix";
int priority = 1; Int32 priority = 1;
bool supressChannelData = false; Boolean supressChannelData = false;
Thread server_thread = null; Thread server_thread = null;
UnixListener listener; UnixListener listener;
UnixServerTransportSink sink; UnixServerTransportSink sink;
ChannelDataStore channel_data; ChannelDataStore channel_data;
int _maxConcurrentConnections = 100; Int32 _maxConcurrentConnections = 100;
ArrayList _activeConnections = new ArrayList(); ArrayList _activeConnections = new ArrayList();
@ -66,26 +66,26 @@ namespace Mono.Remoting.Channels.Unix
// Gets channel data from the chain of channel providers // Gets channel data from the chain of channel providers
channel_data = new ChannelDataStore (null); this.channel_data = new ChannelDataStore (null);
IServerChannelSinkProvider provider = serverSinkProvider; IServerChannelSinkProvider provider = serverSinkProvider;
while (provider != null) while (provider != null)
{ {
provider.GetChannelData(channel_data); provider.GetChannelData(this.channel_data);
provider = provider.Next; provider = provider.Next;
} }
// Creates the sink chain that will process all incoming messages // Creates the sink chain that will process all incoming messages
IServerChannelSink next_sink = ChannelServices.CreateServerChannelSinkChain (serverSinkProvider, this); IServerChannelSink next_sink = ChannelServices.CreateServerChannelSinkChain (serverSinkProvider, this);
sink = new UnixServerTransportSink (next_sink); this.sink = new UnixServerTransportSink (next_sink);
StartListening (null); this.StartListening (null);
} }
public UnixServerChannel (string path) public UnixServerChannel (String path)
{ {
this.path = path; this.path = path;
Init (null); this.Init (null);
} }
public UnixServerChannel (IDictionary properties, public UnixServerChannel (IDictionary properties,
@ -93,81 +93,71 @@ namespace Mono.Remoting.Channels.Unix
{ {
foreach(DictionaryEntry property in properties) foreach(DictionaryEntry property in properties)
{ {
switch((string)property.Key) switch((String)property.Key)
{ {
case "path": case "path":
path = property.Value as string; this.path = property.Value as String;
break; break;
case "priority": case "priority":
priority = Convert.ToInt32(property.Value); this.priority = Convert.ToInt32(property.Value);
break; break;
case "supressChannelData": case "supressChannelData":
supressChannelData = Convert.ToBoolean (property.Value); this.supressChannelData = Convert.ToBoolean (property.Value);
break; break;
} }
} }
Init (serverSinkProvider); this.Init (serverSinkProvider);
} }
public UnixServerChannel (string name, string path, public UnixServerChannel (String name, String path,
IServerChannelSinkProvider serverSinkProvider) IServerChannelSinkProvider serverSinkProvider)
{ {
this.name = name; this.name = name;
this.path = path; this.path = path;
Init (serverSinkProvider); this.Init (serverSinkProvider);
} }
public UnixServerChannel (string name, string path) public UnixServerChannel (String name, String path)
{ {
this.name = name; this.name = name;
this.path = path; this.path = path;
Init (null); this.Init (null);
} }
public object ChannelData public Object ChannelData
{ {
get { get {
if (supressChannelData) return null; if (this.supressChannelData) {
else return channel_data; return null;
} else {
return this.channel_data;
}
} }
} }
public string ChannelName public String ChannelName => this.name;
public Int32 ChannelPriority => this.priority;
public String GetChannelUri() => "unix://" + this.path;
public String[] GetUrlsForUri (String uri)
{ {
get { if (!uri.StartsWith ("/")) {
return name; uri = "/" + uri;
}
} }
public int ChannelPriority String[] chnl_uris = this.channel_data.ChannelUris;
{ String[] result = new String [chnl_uris.Length];
get {
return priority;
}
}
public string GetChannelUri () for (Int32 i = 0; i < chnl_uris.Length; i++) {
{
return "unix://" + path;
}
public string[] GetUrlsForUri (string uri)
{
if (!uri.StartsWith ("/")) uri = "/" + uri;
string [] chnl_uris = channel_data.ChannelUris;
string [] result = new String [chnl_uris.Length];
for (int i = 0; i < chnl_uris.Length; i++)
result [i] = chnl_uris [i] + "?" + uri; result [i] = chnl_uris [i] + "?" + uri;
}
return result; return result;
} }
public string Parse (string url, out string objectURI) public String Parse(String url, out String objectURI) => UnixChannel.ParseUnixURL(url, out objectURI);
{
return UnixChannel.ParseUnixURL (url, out objectURI);
}
void WaitForConnections () void WaitForConnections ()
{ {
@ -175,8 +165,8 @@ namespace Mono.Remoting.Channels.Unix
{ {
while (true) while (true)
{ {
Socket client = listener.AcceptSocket (); Socket client = this.listener.AcceptSocket ();
CreateListenerConnection (client); this.CreateListenerConnection (client);
} }
} }
catch catch
@ -185,34 +175,37 @@ namespace Mono.Remoting.Channels.Unix
internal void CreateListenerConnection (Socket client) internal void CreateListenerConnection (Socket client)
{ {
lock (_activeConnections) lock (this._activeConnections)
{ {
if (_activeConnections.Count >= _maxConcurrentConnections) if (this._activeConnections.Count >= this._maxConcurrentConnections) {
Monitor.Wait (_activeConnections); _ = Monitor.Wait(this._activeConnections);
}
if (server_thread == null) return; // Server was stopped while waiting if (this.server_thread == null) {
return; // Server was stopped while waiting
}
ClientConnection reader = new ClientConnection (this, client, sink); ClientConnection reader = new ClientConnection (this, client, this.sink);
Thread thread = new Thread (new ThreadStart (reader.ProcessMessages)); Thread thread = new Thread (new ThreadStart (reader.ProcessMessages));
thread.Start(); thread.Start();
thread.IsBackground = true; thread.IsBackground = true;
_activeConnections.Add (thread); _ = this._activeConnections.Add(thread);
} }
} }
internal void ReleaseConnection (Thread thread) internal void ReleaseConnection (Thread thread)
{ {
lock (_activeConnections) lock (this._activeConnections)
{ {
_activeConnections.Remove (thread); this._activeConnections.Remove (thread);
Monitor.Pulse (_activeConnections); Monitor.Pulse (this._activeConnections);
} }
} }
public void StartListening (object data) public void StartListening (Object data)
{ {
listener = new UnixListener (path); this.listener = new UnixListener (this.path);
Mono.Unix.Native.Syscall.chmod (path, _ = Mono.Unix.Native.Syscall.chmod(this.path,
Mono.Unix.Native.FilePermissions.S_IRUSR | Mono.Unix.Native.FilePermissions.S_IRUSR |
Mono.Unix.Native.FilePermissions.S_IWUSR | Mono.Unix.Native.FilePermissions.S_IWUSR |
Mono.Unix.Native.FilePermissions.S_IRGRP | Mono.Unix.Native.FilePermissions.S_IRGRP |
@ -220,36 +213,39 @@ namespace Mono.Remoting.Channels.Unix
Mono.Unix.Native.FilePermissions.S_IROTH | Mono.Unix.Native.FilePermissions.S_IROTH |
Mono.Unix.Native.FilePermissions.S_IWOTH); Mono.Unix.Native.FilePermissions.S_IWOTH);
if (server_thread == null) if (this.server_thread == null)
{ {
listener.Start (); this.listener.Start ();
string[] uris = new String [1]; String[] uris = new String [1];
uris = new String [1]; uris = new String [1];
uris [0] = GetChannelUri (); uris [0] = this.GetChannelUri ();
channel_data.ChannelUris = uris; this.channel_data.ChannelUris = uris;
server_thread = new Thread (new ThreadStart (WaitForConnections)); this.server_thread = new Thread (new ThreadStart (this.WaitForConnections));
server_thread.IsBackground = true; this.server_thread.IsBackground = true;
server_thread.Start (); this.server_thread.Start ();
} }
} }
public void StopListening (object data) public void StopListening (Object data)
{ {
if (server_thread == null) return; if (this.server_thread == null) {
return;
}
lock (_activeConnections) lock (this._activeConnections)
{ {
server_thread.Abort (); this.server_thread.Abort ();
server_thread = null; this.server_thread = null;
listener.Stop (); this.listener.Stop ();
foreach (Thread thread in _activeConnections) foreach (Thread thread in this._activeConnections) {
thread.Abort(); thread.Abort();
}
_activeConnections.Clear(); this._activeConnections.Clear();
Monitor.PulseAll (_activeConnections); Monitor.PulseAll (this._activeConnections);
} }
} }
} }
@ -261,40 +257,35 @@ namespace Mono.Remoting.Channels.Unix
Stream _stream; Stream _stream;
UnixServerChannel _serverChannel; UnixServerChannel _serverChannel;
byte[] _buffer = new byte[UnixMessageIO.DefaultStreamBufferSize]; Byte[] _buffer = new Byte[UnixMessageIO.DefaultStreamBufferSize];
public ClientConnection (UnixServerChannel serverChannel, Socket client, UnixServerTransportSink sink) public ClientConnection (UnixServerChannel serverChannel, Socket client, UnixServerTransportSink sink)
{ {
_serverChannel = serverChannel; this._serverChannel = serverChannel;
_client = client; this._client = client;
_sink = sink; this._sink = sink;
} }
public Socket Client { public Socket Client => this._client;
get { return _client; }
}
public byte[] Buffer public Byte[] Buffer => this._buffer;
{
get { return _buffer; }
}
public void ProcessMessages() public void ProcessMessages()
{ {
byte[] buffer = new byte[256]; Byte[] buffer = new Byte[256];
_stream = new BufferedStream (new NetworkStream (_client)); this._stream = new BufferedStream (new NetworkStream (this._client));
try try
{ {
bool end = false; Boolean end = false;
while (!end) while (!end)
{ {
MessageStatus type = UnixMessageIO.ReceiveMessageStatus (_stream, buffer); MessageStatus type = UnixMessageIO.ReceiveMessageStatus (this._stream, buffer);
switch (type) switch (type)
{ {
case MessageStatus.MethodMessage: case MessageStatus.MethodMessage:
_sink.InternalProcessMessage (this, _stream); this._sink.InternalProcessMessage (this, this._stream);
break; break;
case MessageStatus.Unknown: case MessageStatus.Unknown:
@ -311,20 +302,14 @@ namespace Mono.Remoting.Channels.Unix
finally finally
{ {
try { try {
_serverChannel.ReleaseConnection (Thread.CurrentThread); this._serverChannel.ReleaseConnection (Thread.CurrentThread);
_stream.Close(); this._stream.Close();
_client.Close (); this._client.Close ();
} catch { } catch {
} }
} }
} }
public bool IsLocal public Boolean IsLocal => true;
{
get
{
return true;
}
}
} }
} }

View File

@ -35,95 +35,73 @@ using System.Runtime.Remoting.Messaging;
using System.IO; using System.IO;
using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels;
namespace Mono.Remoting.Channels.Unix namespace Mono.Remoting.Channels.Unix {
{ internal class UnixServerTransportSink : IServerChannelSink, IChannelSinkBase {
internal class UnixServerTransportSink : IServerChannelSink, IChannelSinkBase
{
IServerChannelSink next_sink; IServerChannelSink next_sink;
public UnixServerTransportSink (IServerChannelSink next) public UnixServerTransportSink(IServerChannelSink next) => this.next_sink = next;
{
next_sink = next;
}
public IServerChannelSink NextChannelSink public IServerChannelSink NextChannelSink => this.next_sink;
{
get
{
return next_sink;
}
}
public IDictionary Properties public IDictionary Properties {
{ get {
get if(this.next_sink != null) {
{ return this.next_sink.Properties;
if (next_sink != null) return next_sink.Properties; } else {
else return null;
}
}
public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
IMessage msg, ITransportHeaders headers, Stream responseStream)
{
ClientConnection connection = (ClientConnection)state;
NetworkStream stream = new NetworkStream (connection.Client);
UnixMessageIO.SendMessageStream (stream, responseStream, headers, connection.Buffer);
stream.Flush ();
stream.Close ();
}
public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
IMessage msg, ITransportHeaders headers)
{
return null; return null;
} }
}
}
public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack, public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state,
IMessage msg, ITransportHeaders headers, Stream responseStream) {
ClientConnection connection = (ClientConnection)state;
NetworkStream stream = new NetworkStream(connection.Client);
UnixMessageIO.SendMessageStream(stream, responseStream, headers, connection.Buffer);
stream.Flush();
stream.Close();
}
public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state,
IMessage msg, ITransportHeaders headers) => null;
public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
IMessage requestMsg, IMessage requestMsg,
ITransportHeaders requestHeaders, ITransportHeaders requestHeaders,
Stream requestStream, Stream requestStream,
out IMessage responseMsg, out IMessage responseMsg,
out ITransportHeaders responseHeaders, out ITransportHeaders responseHeaders,
out Stream responseStream) out Stream responseStream) =>
{
// this is the first sink, and UnixServerChannel does not call it. // this is the first sink, and UnixServerChannel does not call it.
throw new NotSupportedException (); throw new NotSupportedException();
}
internal void InternalProcessMessage (ClientConnection connection, Stream stream) internal void InternalProcessMessage(ClientConnection connection, Stream stream) {
{
// Reads the headers and the request stream // Reads the headers and the request stream
Stream requestStream; Stream requestStream;
ITransportHeaders requestHeaders;
requestStream = UnixMessageIO.ReceiveMessageStream (stream, out requestHeaders, connection.Buffer); requestStream = UnixMessageIO.ReceiveMessageStream(stream, out ITransportHeaders requestHeaders, connection.Buffer);
/* try { /* try {
PeerCred cred = connection.Client.PeerCredential; PeerCred cred = connection.Client.PeerCredential;
requestHeaders["__uid"] = cred.UserID; requestHeaders["__uid"] = cred.UserID;
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine ("Couldn't get the peer cred: " + e); Console.WriteLine ("Couldn't get the peer cred: " + e);
} }
*/ */
// Pushes the connection object together with the sink. This information // Pushes the connection object together with the sink. This information
// will be used for sending the response in an async call. // will be used for sending the response in an async call.
ServerChannelSinkStack sinkStack = new ServerChannelSinkStack(); ServerChannelSinkStack sinkStack = new ServerChannelSinkStack();
sinkStack.Push(this, connection); sinkStack.Push(this, connection);
ITransportHeaders responseHeaders;
Stream responseStream;
IMessage responseMsg;
ServerProcessing proc = next_sink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); ServerProcessing proc = this.next_sink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream);
switch (proc) switch(proc) {
{
case ServerProcessing.Complete: case ServerProcessing.Complete:
UnixMessageIO.SendMessageStream (stream, responseStream, responseHeaders, connection.Buffer); UnixMessageIO.SendMessageStream(stream, responseStream, responseHeaders, connection.Buffer);
stream.Flush (); stream.Flush();
break; break;
case ServerProcessing.Async: case ServerProcessing.Async:

View File

@ -73,71 +73,70 @@ namespace Mono.Unix.Native {
{ {
// The readonly fields (1) shouldn't be modified, and (2) should only be // The readonly fields (1) shouldn't be modified, and (2) should only be
// used when `overloads' is locked. // used when `overloads' is locked.
private readonly string library; private readonly String library;
private readonly string method; private readonly String method;
private readonly Type returnType; private readonly Type returnType;
private readonly AssemblyName assemblyName; private readonly AssemblyName assemblyName;
private readonly AssemblyBuilder assemblyBuilder; private readonly AssemblyBuilder assemblyBuilder;
private readonly ModuleBuilder moduleBuilder; private readonly ModuleBuilder moduleBuilder;
private Hashtable overloads; private readonly Hashtable overloads;
public CdeclFunction (string library, string method) public CdeclFunction (String library, String method)
: this (library, method, typeof(void)) : this (library, method, typeof(void))
{ {
} }
public CdeclFunction (string library, string method, Type returnType) public CdeclFunction (String library, String method, Type returnType)
{ {
this.library = library; this.library = library;
this.method = method; this.method = method;
this.returnType = returnType; this.returnType = returnType;
this.overloads = new Hashtable (); this.overloads = new Hashtable ();
this.assemblyName = new AssemblyName (); this.assemblyName = new AssemblyName {
this.assemblyName.Name = "Mono.Posix.Imports." + library; Name = "Mono.Posix.Imports." + library
};
this.assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly ( this.assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
assemblyName, AssemblyBuilderAccess.Run); this.assemblyName, AssemblyBuilderAccess.Run);
this.moduleBuilder = assemblyBuilder.DefineDynamicModule (assemblyName.Name); this.moduleBuilder = this.assemblyBuilder.DefineDynamicModule (this.assemblyName.Name);
} }
public object Invoke (object[] parameters) public Object Invoke (Object[] parameters)
{ {
Type[] parameterTypes = GetParameterTypes (parameters); Type[] parameterTypes = GetParameterTypes (parameters);
MethodInfo m = CreateMethod (parameterTypes); MethodInfo m = this.CreateMethod (parameterTypes);
return m.Invoke (null, parameters); return m.Invoke (null, parameters);
} }
private MethodInfo CreateMethod (Type[] parameterTypes) private MethodInfo CreateMethod (Type[] parameterTypes)
{ {
string typeName = GetTypeName (parameterTypes); String typeName = this.GetTypeName (parameterTypes);
lock (overloads) { lock (this.overloads) {
MethodInfo mi = (MethodInfo) overloads [typeName]; MethodInfo mi = (MethodInfo)this.overloads [typeName];
if (mi != null) { if (mi != null) {
return mi; return mi;
} }
TypeBuilder tb = CreateType (typeName); TypeBuilder tb = this.CreateType (typeName);
/* MethodBuilder mb = */ tb.DefinePInvokeMethod ( /* MethodBuilder mb = */
method, _ = tb.DefinePInvokeMethod(
library, this.method,
this.library,
MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public, MethodAttributes.PinvokeImpl | MethodAttributes.Static | MethodAttributes.Public,
CallingConventions.Standard, CallingConventions.Standard,
returnType, this.returnType,
parameterTypes, parameterTypes,
CallingConvention.Cdecl, CallingConvention.Cdecl,
CharSet.Ansi); CharSet.Ansi);
mi = tb.CreateType ().GetMethod (method); mi = tb.CreateType ().GetMethod (this.method);
overloads.Add (typeName, mi); this.overloads.Add (typeName, mi);
return mi; return mi;
} }
} }
private TypeBuilder CreateType (string typeName) private TypeBuilder CreateType(String typeName) => this.moduleBuilder.DefineType(typeName, TypeAttributes.Public);
{
return moduleBuilder.DefineType (typeName, TypeAttributes.Public);
}
private static Type GetMarshalType (Type t) private static Type GetMarshalType (Type t)
{ {
@ -145,42 +144,47 @@ namespace Mono.Unix.Native {
// types < sizeof(int) are marshaled as ints // types < sizeof(int) are marshaled as ints
case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte:
case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int16: case TypeCode.Int32:
return typeof(int); return typeof(Int32);
case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32:
return typeof(uint); return typeof(UInt32);
case TypeCode.Int64: case TypeCode.Int64:
return typeof(long); return typeof(Int64);
case TypeCode.UInt64: case TypeCode.UInt64:
return typeof(ulong); return typeof(UInt64);
case TypeCode.Single: case TypeCode.Double: case TypeCode.Single: case TypeCode.Double:
return typeof(double); return typeof(Double);
default: default:
return t; return t;
} }
} }
private string GetTypeName (Type[] parameterTypes) private String GetTypeName (Type[] parameterTypes)
{ {
StringBuilder sb = new StringBuilder (); StringBuilder sb = new StringBuilder ();
sb.Append ("[").Append (library).Append ("] ").Append (method); _ = sb.Append("[").Append(this.library).Append("] ").Append(this.method);
sb.Append ("("); _ = sb.Append("(");
if (parameterTypes.Length > 0) if (parameterTypes.Length > 0) {
sb.Append (parameterTypes [0]); _ = sb.Append(parameterTypes[0]);
for (int i = 1; i < parameterTypes.Length; ++i) }
sb.Append (",").Append (parameterTypes [i]);
sb.Append (") : ").Append (returnType.FullName); for (Int32 i = 1; i < parameterTypes.Length; ++i) {
_ = sb.Append(",").Append(parameterTypes[i]);
}
_ = sb.Append(") : ").Append(this.returnType.FullName);
return sb.ToString (); return sb.ToString ();
} }
private static Type[] GetParameterTypes (object[] parameters) private static Type[] GetParameterTypes (Object[] parameters)
{ {
Type[] parameterTypes = new Type [parameters.Length]; Type[] parameterTypes = new Type [parameters.Length];
for (int i = 0; i < parameters.Length; ++i) for (Int32 i = 0; i < parameters.Length; ++i) {
parameterTypes [i] = GetMarshalType (parameters [i].GetType ()); parameterTypes [i] = GetMarshalType (parameters [i].GetType ());
}
return parameterTypes; return parameterTypes;
} }
} }

View File

@ -34,41 +34,35 @@ namespace Mono.Unix.Native {
class FileNameMarshaler : ICustomMarshaler { class FileNameMarshaler : ICustomMarshaler {
private static FileNameMarshaler Instance = new FileNameMarshaler (); private static readonly FileNameMarshaler Instance = new FileNameMarshaler ();
public static ICustomMarshaler GetInstance (string s) [System.Diagnostics.CodeAnalysis.SuppressMessage("Stil", "IDE0060:Nicht verwendete Parameter entfernen", Justification = "<Ausstehend>")]
{ public static ICustomMarshaler GetInstance(String s) => Instance;
return Instance;
}
public void CleanUpManagedData (object o) public void CleanUpManagedData (Object o)
{ {
} }
public void CleanUpNativeData (IntPtr pNativeData) public void CleanUpNativeData(IntPtr pNativeData) =>
{
// Console.WriteLine ("# FileNameMarshaler.CleanUpManagedData ({0:x})", pNativeData); // Console.WriteLine ("# FileNameMarshaler.CleanUpManagedData ({0:x})", pNativeData);
UnixMarshal.FreeHeap (pNativeData); UnixMarshal.FreeHeap(pNativeData);
}
public int GetNativeDataSize () public Int32 GetNativeDataSize() => IntPtr.Size;
{
return IntPtr.Size;
}
public IntPtr MarshalManagedToNative (object obj) public IntPtr MarshalManagedToNative (Object obj)
{ {
string s = obj as string; if(!(obj is String s)) {
if (s == null)
return IntPtr.Zero; return IntPtr.Zero;
}
IntPtr p = UnixMarshal.StringToHeap (s, UnixEncoding.Instance); IntPtr p = UnixMarshal.StringToHeap (s, UnixEncoding.Instance);
// Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged for `{0}'={1:x}", s, p); // Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged for `{0}'={1:x}", s, p);
return p; return p;
} }
public object MarshalNativeToManaged (IntPtr pNativeData) public Object MarshalNativeToManaged (IntPtr pNativeData)
{ {
string s = UnixMarshal.PtrToString (pNativeData, UnixEncoding.Instance); String s = UnixMarshal.PtrToString (pNativeData, UnixEncoding.Instance);
// Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged ({0:x})=`{1}'", // Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged ({0:x})=`{1}'",
// pNativeData, s); // pNativeData, s);
return s; return s;

View File

@ -36,25 +36,17 @@ using System;
AttributeTargets.Field | AttributeTargets.Field |
AttributeTargets.Struct)] AttributeTargets.Struct)]
internal class MapAttribute : Attribute { internal class MapAttribute : Attribute {
private string nativeType;
private string suppressFlags;
public MapAttribute () public MapAttribute ()
{ {
} }
public MapAttribute (string nativeType) public MapAttribute(String nativeType) => this.NativeType = nativeType;
{
this.nativeType = nativeType; public String NativeType {
get;
} }
public string NativeType { public String SuppressFlags { get;
get {return nativeType;} set; }
}
public string SuppressFlags {
get {return suppressFlags;}
set {suppressFlags = value;}
}
} }

View File

@ -14,7 +14,7 @@ using Mono.Unix.Android;
namespace Mono.Unix.Native { namespace Mono.Unix.Native {
[CLSCompliant (false)] //[CLSCompliant (false)]
public sealed /* static */ partial class NativeConvert public sealed /* static */ partial class NativeConvert
{ {
// //
@ -32,44 +32,45 @@ namespace Mono.Unix.Native {
} }
#else #else
[DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")] [DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")]
private static extern int FromRealTimeSignum (Int32 offset, out Int32 rval); private static extern Int32 FromRealTimeSignum (Int32 offset, out Int32 rval);
#endif #endif
// convert a realtime signal to os signal // convert a realtime signal to os signal
public static int FromRealTimeSignum (RealTimeSignum sig) public static Int32 FromRealTimeSignum (RealTimeSignum sig)
{ {
int sigNum; if(FromRealTimeSignum(sig.Offset, out Int32 sigNum) == -1) {
if (FromRealTimeSignum (sig.Offset, out sigNum) == -1) ThrowArgumentException(sig.Offset);
ThrowArgumentException (sig.Offset); }
return sigNum; return sigNum;
} }
// convert an offset to an rt signum // convert an offset to an rt signum
public static RealTimeSignum ToRealTimeSignum (int offset) public static RealTimeSignum ToRealTimeSignum(Int32 offset) => new RealTimeSignum(offset);
{
return new RealTimeSignum (offset);
}
// convert from octal representation. // convert from octal representation.
public static FilePermissions FromOctalPermissionString (string value) public static FilePermissions FromOctalPermissionString (String value)
{ {
uint n = Convert.ToUInt32 (value, 8); UInt32 n = Convert.ToUInt32 (value, 8);
return ToFilePermissions (n); return ToFilePermissions (n);
} }
public static string ToOctalPermissionString (FilePermissions value) public static String ToOctalPermissionString (FilePermissions value)
{ {
string s = Convert.ToString ((int) (value & ~FilePermissions.S_IFMT), 8); String s = Convert.ToString ((Int32) (value & ~FilePermissions.S_IFMT), 8);
return new string ('0', 4-s.Length) + s; return new String('0', 4-s.Length) + s;
} }
public static FilePermissions FromUnixPermissionString (string value) public static FilePermissions FromUnixPermissionString (String value)
{ {
if (value == null) if (value == null) {
throw new ArgumentNullException ("value"); throw new ArgumentNullException ("value");
if (value.Length != 9 && value.Length != 10) }
throw new ArgumentException ("value", "must contain 9 or 10 characters");
int i = 0; if (value.Length != 9 && value.Length != 10) {
throw new ArgumentException ("value", "must contain 9 or 10 characters");
}
Int32 i = 0;
FilePermissions perms = new FilePermissions (); FilePermissions perms = new FilePermissions ();
if (value.Length == 10) { if (value.Length == 10) {
@ -98,7 +99,7 @@ namespace Mono.Unix.Native {
return perms; return perms;
} }
private static FilePermissions GetUnixPermissionDevice (char value) private static FilePermissions GetUnixPermissionDevice (Char value)
{ {
switch (value) { switch (value) {
case 'd': return FilePermissions.S_IFDIR; case 'd': return FilePermissions.S_IFDIR;
@ -114,35 +115,41 @@ namespace Mono.Unix.Native {
} }
private static FilePermissions GetUnixPermissionGroup ( private static FilePermissions GetUnixPermissionGroup (
char read, FilePermissions readb, Char read, FilePermissions readb,
char write, FilePermissions writeb, Char write, FilePermissions writeb,
char exec, FilePermissions execb, Char exec, FilePermissions execb,
char xboth, char xbitonly, FilePermissions xbit) Char xboth, Char xbitonly, FilePermissions xbit)
{ {
FilePermissions perms = new FilePermissions (); FilePermissions perms = new FilePermissions ();
if (read == 'r') if (read == 'r') {
perms |= readb; perms |= readb;
if (write == 'w') }
if (write == 'w') {
perms |= writeb; perms |= writeb;
if (exec == 'x') }
if (exec == 'x') {
perms |= execb; perms |= execb;
else if (exec == xbitonly) } else if (exec == xbitonly) {
perms |= xbit; perms |= xbit;
else if (exec == xboth) } else if (exec == xboth) {
perms |= (execb | xbit); perms |= execb | xbit;
}
return perms; return perms;
} }
// Create ls(1) drwxrwxrwx permissions display // Create ls(1) drwxrwxrwx permissions display
public static string ToUnixPermissionString (FilePermissions value) public static String ToUnixPermissionString (FilePermissions value)
{ {
char [] access = new char[] { Char[] access = new Char[] {
'-', // device '-', // device
'-', '-', '-', // owner '-', '-', '-', // owner
'-', '-', '-', // group '-', '-', '-', // group
'-', '-', '-', // other '-', '-', '-', // other
}; };
bool have_device = true; Boolean have_device = true;
switch (value & FilePermissions.S_IFMT) { switch (value & FilePermissions.S_IFMT) {
case FilePermissions.S_IFDIR: access [0] = 'd'; break; case FilePermissions.S_IFDIR: access [0] = 'd'; break;
case FilePermissions.S_IFCHR: access [0] = 'c'; break; case FilePermissions.S_IFCHR: access [0] = 'c'; break;
@ -163,37 +170,35 @@ namespace Mono.Unix.Native {
FilePermissions.S_IROTH, FilePermissions.S_IWOTH, FilePermissions.S_IXOTH, FilePermissions.S_IROTH, FilePermissions.S_IWOTH, FilePermissions.S_IXOTH,
't', 'T', FilePermissions.S_ISVTX); 't', 'T', FilePermissions.S_ISVTX);
return have_device return have_device
? new string (access) ? new String(access)
: new string (access, 1, 9); : new String(access, 1, 9);
} }
private static void SetUnixPermissionGroup (FilePermissions value, private static void SetUnixPermissionGroup (FilePermissions value,
char[] access, int index, Char[] access, Int32 index,
FilePermissions read, FilePermissions write, FilePermissions exec, FilePermissions read, FilePermissions write, FilePermissions exec,
char both, char setonly, FilePermissions setxbit) Char both, Char setonly, FilePermissions setxbit)
{ {
if (UnixFileSystemInfo.IsSet (value, read)) if (UnixFileSystemInfo.IsSet (value, read)) {
access [index] = 'r'; access [index] = 'r';
if (UnixFileSystemInfo.IsSet (value, write)) }
if (UnixFileSystemInfo.IsSet (value, write)) {
access [index+1] = 'w'; access [index+1] = 'w';
}
access [index+2] = GetSymbolicMode (value, exec, both, setonly, setxbit); access [index+2] = GetSymbolicMode (value, exec, both, setonly, setxbit);
} }
// Implement the GNU ls(1) permissions spec; see `info coreutils ls`, // Implement the GNU ls(1) permissions spec; see `info coreutils ls`,
// section 10.1.2, the `-l' argument information. // section 10.1.2, the `-l' argument information.
private static char GetSymbolicMode (FilePermissions value, private static Char GetSymbolicMode (FilePermissions value,
FilePermissions xbit, char both, char setonly, FilePermissions setxbit) FilePermissions xbit, Char both, Char setonly, FilePermissions setxbit)
{ {
bool is_x = UnixFileSystemInfo.IsSet (value, xbit); Boolean is_x = UnixFileSystemInfo.IsSet (value, xbit);
bool is_sx = UnixFileSystemInfo.IsSet (value, setxbit); Boolean is_sx = UnixFileSystemInfo.IsSet (value, setxbit);
if (is_x && is_sx) return is_x && is_sx ? both : is_sx ? setonly : is_x ? 'x' : '-';
return both;
if (is_sx)
return setonly;
if (is_x)
return 'x';
return '-';
} }
public static readonly DateTime UnixEpoch = public static readonly DateTime UnixEpoch =
@ -203,35 +208,25 @@ namespace Mono.Unix.Native {
public static readonly TimeSpan LocalUtcOffset = public static readonly TimeSpan LocalUtcOffset =
TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow); TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
public static DateTime ToDateTime (long time) public static DateTime ToDateTime(Int64 time) => FromTimeT(time);
{
return FromTimeT (time);
}
public static DateTime ToDateTime (long time, long nanoTime) public static DateTime ToDateTime(Int64 time, Int64 nanoTime) => FromTimeT(time).AddMilliseconds(nanoTime / 1000);
{
return FromTimeT (time).AddMilliseconds (nanoTime / 1000);
}
public static long FromDateTime (DateTime time) public static Int64 FromDateTime(DateTime time) => ToTimeT(time);
{
return ToTimeT (time);
}
public static DateTime FromTimeT (long time) public static DateTime FromTimeT(Int64 time) => UnixEpoch.AddSeconds(time).ToLocalTime();
{
return UnixEpoch.AddSeconds (time).ToLocalTime ();
}
public static long ToTimeT (DateTime time) public static Int64 ToTimeT (DateTime time)
{ {
if (time.Kind == DateTimeKind.Unspecified) if (time.Kind == DateTimeKind.Unspecified) {
throw new ArgumentException ("DateTimeKind.Unspecified is not supported. Use Local or Utc times.", "time"); throw new ArgumentException ("DateTimeKind.Unspecified is not supported. Use Local or Utc times.", "time");
}
if (time.Kind == DateTimeKind.Local) if (time.Kind == DateTimeKind.Local) {
time = time.ToUniversalTime (); time = time.ToUniversalTime ();
}
return (long) (time - UnixEpoch).TotalSeconds; return (Int64) (time - UnixEpoch).TotalSeconds;
} }
public static OpenFlags ToOpenFlags (FileMode mode, FileAccess access) public static OpenFlags ToOpenFlags (FileMode mode, FileAccess access)
@ -261,9 +256,9 @@ namespace Mono.Unix.Native {
} }
// Is O_LARGEFILE supported? // Is O_LARGEFILE supported?
int _v; if(TryFromOpenFlags(OpenFlags.O_LARGEFILE, out _)) {
if (TryFromOpenFlags (OpenFlags.O_LARGEFILE, out _v))
flags |= OpenFlags.O_LARGEFILE; flags |= OpenFlags.O_LARGEFILE;
}
switch (access) { switch (access) {
case FileAccess.Read: case FileAccess.Read:
@ -282,7 +277,7 @@ namespace Mono.Unix.Native {
return flags; return flags;
} }
public static string ToFopenMode (FileAccess access) public static String ToFopenMode (FileAccess access)
{ {
switch (access) { switch (access) {
case FileAccess.Read: return "rb"; case FileAccess.Read: return "rb";
@ -292,7 +287,7 @@ namespace Mono.Unix.Native {
} }
} }
public static string ToFopenMode (FileMode mode) public static String ToFopenMode (FileMode mode)
{ {
switch (mode) { switch (mode) {
case FileMode.CreateNew: case FileMode.Create: return "w+b"; case FileMode.CreateNew: case FileMode.Create: return "w+b";
@ -303,19 +298,19 @@ namespace Mono.Unix.Native {
} }
} }
private static readonly string[][] fopen_modes = new string[][]{ private static readonly String[][] fopen_modes = new String[][]{
// Read Write ReadWrite // Read Write ReadWrite
/* FileMode.CreateNew: */ new string[]{"Can't Read+Create", "wb", "w+b"}, /* FileMode.CreateNew: */ new String[]{"Can't Read+Create", "wb", "w+b"},
/* FileMode.Create: */ new string[]{"Can't Read+Create", "wb", "w+b"}, /* FileMode.Create: */ new String[]{"Can't Read+Create", "wb", "w+b"},
/* FileMode.Open: */ new string[]{"rb", "wb", "r+b"}, /* FileMode.Open: */ new String[]{"rb", "wb", "r+b"},
/* FileMode.OpenOrCreate: */ new string[]{"rb", "wb", "r+b"}, /* FileMode.OpenOrCreate: */ new String[]{"rb", "wb", "r+b"},
/* FileMode.Truncate: */ new string[]{"Cannot Truncate and Read","wb", "w+b"}, /* FileMode.Truncate: */ new String[]{"Cannot Truncate and Read","wb", "w+b"},
/* FileMode.Append: */ new string[]{"Cannot Append and Read", "ab", "a+b"}, /* FileMode.Append: */ new String[]{"Cannot Append and Read", "ab", "a+b"},
}; };
public static string ToFopenMode (FileMode mode, FileAccess access) public static String ToFopenMode (FileMode mode, FileAccess access)
{ {
int fm = -1, fa = -1; Int32 fm = -1, fa = -1;
switch (mode) { switch (mode) {
case FileMode.CreateNew: fm = 0; break; case FileMode.CreateNew: fm = 0; break;
case FileMode.Create: fm = 1; break; case FileMode.Create: fm = 1; break;
@ -330,149 +325,142 @@ namespace Mono.Unix.Native {
case FileAccess.ReadWrite: fa = 2; break; case FileAccess.ReadWrite: fa = 2; break;
} }
if (fm == -1) if (fm == -1) {
throw new ArgumentOutOfRangeException ("mode"); throw new ArgumentOutOfRangeException ("mode");
if (fa == -1) }
throw new ArgumentOutOfRangeException ("access");
string fopen_mode = fopen_modes [fm][fa]; if (fa == -1) {
if (fopen_mode [0] != 'r' && fopen_mode [0] != 'w' && fopen_mode [0] != 'a') throw new ArgumentOutOfRangeException ("access");
}
String fopen_mode = fopen_modes [fm][fa];
if (fopen_mode [0] != 'r' && fopen_mode [0] != 'w' && fopen_mode [0] != 'a') {
throw new ArgumentException (fopen_mode); throw new ArgumentException (fopen_mode);
}
return fopen_mode; return fopen_mode;
} }
[DllImport (LIB, EntryPoint="Mono_Posix_FromStat")] [DllImport (LIB, EntryPoint="Mono_Posix_FromStat")]
private static extern int FromStat (ref Stat source, IntPtr destination); private static extern Int32 FromStat (ref Stat source, IntPtr destination);
public static bool TryCopy (ref Stat source, IntPtr destination) public static Boolean TryCopy(ref Stat source, IntPtr destination) => FromStat(ref source, destination) == 0;
{
return FromStat (ref source, destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_ToStat")] [DllImport (LIB, EntryPoint="Mono_Posix_ToStat")]
private static extern int ToStat (IntPtr source, out Stat destination); private static extern Int32 ToStat (IntPtr source, out Stat destination);
public static bool TryCopy (IntPtr source, out Stat destination) public static Boolean TryCopy(IntPtr source, out Stat destination) => ToStat(source, out destination) == 0;
{
return ToStat (source, out destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_FromStatvfs")] [DllImport (LIB, EntryPoint="Mono_Posix_FromStatvfs")]
private static extern int FromStatvfs (ref Statvfs source, IntPtr destination); private static extern Int32 FromStatvfs (ref Statvfs source, IntPtr destination);
public static bool TryCopy (ref Statvfs source, IntPtr destination) public static Boolean TryCopy(ref Statvfs source, IntPtr destination) => FromStatvfs(ref source, destination) == 0;
{
return FromStatvfs (ref source, destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_ToStatvfs")] [DllImport (LIB, EntryPoint="Mono_Posix_ToStatvfs")]
private static extern int ToStatvfs (IntPtr source, out Statvfs destination); private static extern Int32 ToStatvfs (IntPtr source, out Statvfs destination);
public static bool TryCopy (IntPtr source, out Statvfs destination) public static Boolean TryCopy(IntPtr source, out Statvfs destination) => ToStatvfs(source, out destination) == 0;
{
return ToStatvfs (source, out destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_FromInAddr")] [DllImport (LIB, EntryPoint="Mono_Posix_FromInAddr")]
private static extern int FromInAddr (ref InAddr source, IntPtr destination); private static extern Int32 FromInAddr (ref InAddr source, IntPtr destination);
public static bool TryCopy (ref InAddr source, IntPtr destination) public static Boolean TryCopy(ref InAddr source, IntPtr destination) => FromInAddr(ref source, destination) == 0;
{
return FromInAddr (ref source, destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_ToInAddr")] [DllImport (LIB, EntryPoint="Mono_Posix_ToInAddr")]
private static extern int ToInAddr (IntPtr source, out InAddr destination); private static extern Int32 ToInAddr (IntPtr source, out InAddr destination);
public static bool TryCopy (IntPtr source, out InAddr destination) public static Boolean TryCopy(IntPtr source, out InAddr destination) => ToInAddr(source, out destination) == 0;
{
return ToInAddr (source, out destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_FromIn6Addr")] [DllImport (LIB, EntryPoint="Mono_Posix_FromIn6Addr")]
private static extern int FromIn6Addr (ref In6Addr source, IntPtr destination); private static extern Int32 FromIn6Addr (ref In6Addr source, IntPtr destination);
public static bool TryCopy (ref In6Addr source, IntPtr destination) public static Boolean TryCopy(ref In6Addr source, IntPtr destination) => FromIn6Addr(ref source, destination) == 0;
{
return FromIn6Addr (ref source, destination) == 0;
}
[DllImport (LIB, EntryPoint="Mono_Posix_ToIn6Addr")] [DllImport (LIB, EntryPoint="Mono_Posix_ToIn6Addr")]
private static extern int ToIn6Addr (IntPtr source, out In6Addr destination); private static extern Int32 ToIn6Addr (IntPtr source, out In6Addr destination);
public static bool TryCopy (IntPtr source, out In6Addr destination) public static Boolean TryCopy(IntPtr source, out In6Addr destination) => ToIn6Addr(source, out destination) == 0;
{
return ToIn6Addr (source, out destination) == 0;
}
public static InAddr ToInAddr (System.Net.IPAddress address) public static InAddr ToInAddr (System.Net.IPAddress address)
{ {
if (address == null) if (address == null) {
throw new ArgumentNullException ("address"); throw new ArgumentNullException ("address");
if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) }
if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) {
throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork"); throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork");
}
return new InAddr (address.GetAddressBytes ()); return new InAddr (address.GetAddressBytes ());
} }
public static System.Net.IPAddress ToIPAddress (InAddr address) public static System.Net.IPAddress ToIPAddress (InAddr address)
{ {
var bytes = new byte[4]; Byte[] bytes = new Byte[4];
address.CopyTo (bytes, 0); address.CopyTo (bytes, 0);
return new System.Net.IPAddress (bytes); return new System.Net.IPAddress (bytes);
} }
public static In6Addr ToIn6Addr (System.Net.IPAddress address) public static In6Addr ToIn6Addr (System.Net.IPAddress address)
{ {
if (address == null) if (address == null) {
throw new ArgumentNullException ("address"); throw new ArgumentNullException ("address");
if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) }
if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) {
throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6"); throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6");
}
return new In6Addr (address.GetAddressBytes ()); return new In6Addr (address.GetAddressBytes ());
} }
public static System.Net.IPAddress ToIPAddress (In6Addr address) public static System.Net.IPAddress ToIPAddress (In6Addr address)
{ {
var bytes = new byte[16]; Byte[] bytes = new Byte[16];
address.CopyTo (bytes, 0); address.CopyTo (bytes, 0);
return new System.Net.IPAddress (bytes); return new System.Net.IPAddress (bytes);
} }
[DllImport (LIB, EntryPoint="Mono_Posix_FromSockaddr")] [DllImport (LIB, EntryPoint="Mono_Posix_FromSockaddr")]
private static extern unsafe int FromSockaddr (_SockaddrHeader* source, IntPtr destination); private static extern unsafe Int32 FromSockaddr (_SockaddrHeader* source, IntPtr destination);
public static unsafe bool TryCopy (Sockaddr source, IntPtr destination) public static unsafe Boolean TryCopy (Sockaddr source, IntPtr destination)
{ {
if (source == null) if (source == null) {
throw new ArgumentNullException ("source"); throw new ArgumentNullException ("source");
byte[] array = Sockaddr.GetDynamicData (source); }
Byte[] array = Sockaddr.GetDynamicData (source);
// SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
if (source.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) { if (source.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
Marshal.Copy (array, 0, destination, (int) source.GetDynamicLength ()); Marshal.Copy (array, 0, destination, (Int32) source.GetDynamicLength ());
return true; return true;
} }
fixed (SockaddrType* addr = &Sockaddr.GetAddress (source).type) fixed (SockaddrType* addr = &Sockaddr.GetAddress (source).type)
fixed (byte* data = array) { fixed (Byte* data = array) {
var dyn = new _SockaddrDynamic (source, data, useMaxLength: false); _SockaddrDynamic dyn = new _SockaddrDynamic (source, data, useMaxLength: false);
return FromSockaddr (Sockaddr.GetNative (&dyn, addr), destination) == 0; return FromSockaddr (Sockaddr.GetNative (&dyn, addr), destination) == 0;
} }
} }
[DllImport (LIB, EntryPoint="Mono_Posix_ToSockaddr")] [DllImport (LIB, EntryPoint="Mono_Posix_ToSockaddr")]
private static extern unsafe int ToSockaddr (IntPtr source, long size, _SockaddrHeader* destination); private static extern unsafe Int32 ToSockaddr (IntPtr source, Int64 size, _SockaddrHeader* destination);
public static unsafe bool TryCopy (IntPtr source, long size, Sockaddr destination) public static unsafe Boolean TryCopy (IntPtr source, Int64 size, Sockaddr destination)
{ {
if (destination == null) if (destination == null) {
throw new ArgumentNullException ("destination"); throw new ArgumentNullException ("destination");
byte[] array = Sockaddr.GetDynamicData (destination); }
Byte[] array = Sockaddr.GetDynamicData (destination);
fixed (SockaddrType* addr = &Sockaddr.GetAddress (destination).type) fixed (SockaddrType* addr = &Sockaddr.GetAddress (destination).type)
fixed (byte* data = Sockaddr.GetDynamicData (destination)) { fixed (Byte* data = Sockaddr.GetDynamicData (destination)) {
var dyn = new _SockaddrDynamic (destination, data, useMaxLength: true); _SockaddrDynamic dyn = new _SockaddrDynamic (destination, data, useMaxLength: true);
var r = ToSockaddr (source, size, Sockaddr.GetNative (&dyn, addr)); Int32 r = ToSockaddr (source, size, Sockaddr.GetNative (&dyn, addr));
dyn.Update (destination); dyn.Update (destination);
// SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
if (r == 0 && destination.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) { if (r == 0 && destination.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
Marshal.Copy (source, array, 0, (int) destination.GetDynamicLength ()); Marshal.Copy (source, array, 0, (Int32) destination.GetDynamicLength ());
} }
return r == 0; return r == 0;
} }

View File

@ -6,7 +6,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Mono.Unix.Native;
namespace Mono.Unix.Native { namespace Mono.Unix.Native {

View File

@ -25,57 +25,39 @@
// //
using System; using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace Mono.Unix.Native { namespace Mono.Unix.Native {
public struct RealTimeSignum public struct RealTimeSignum
: IEquatable <RealTimeSignum> : IEquatable <RealTimeSignum>
{ {
private int rt_offset; private static readonly Int32 MaxOffset = UnixSignal.GetSIGRTMAX () - UnixSignal.GetSIGRTMIN () - 1;
private static readonly int MaxOffset = UnixSignal.GetSIGRTMAX () - UnixSignal.GetSIGRTMIN () - 1;
public static readonly RealTimeSignum MinValue = new RealTimeSignum (0); public static readonly RealTimeSignum MinValue = new RealTimeSignum (0);
public static readonly RealTimeSignum MaxValue = new RealTimeSignum (MaxOffset); public static readonly RealTimeSignum MaxValue = new RealTimeSignum (MaxOffset);
public RealTimeSignum (int offset) public RealTimeSignum (Int32 offset)
{ {
if (offset < 0) if (offset < 0) {
throw new ArgumentOutOfRangeException ("Offset cannot be negative"); throw new ArgumentOutOfRangeException ("Offset cannot be negative");
if (offset > MaxOffset) }
if (offset > MaxOffset) {
throw new ArgumentOutOfRangeException ("Offset greater than maximum supported SIGRT"); throw new ArgumentOutOfRangeException ("Offset greater than maximum supported SIGRT");
rt_offset = offset;
} }
public int Offset { this.Offset = offset;
get { return rt_offset; }
} }
public override int GetHashCode () public Int32 Offset { get; }
{
return rt_offset.GetHashCode ();
}
public override bool Equals (object obj) public override Int32 GetHashCode() => this.Offset.GetHashCode();
{
if ((obj == null) || (obj.GetType () != GetType ()))
return false;
return Equals ((RealTimeSignum)obj);
}
public bool Equals (RealTimeSignum value) public override Boolean Equals(Object obj) => obj == null || obj.GetType() != this.GetType() ? false : this.Equals((RealTimeSignum)obj);
{
return Offset == value.Offset;
}
public static bool operator== (RealTimeSignum lhs, RealTimeSignum rhs) public Boolean Equals(RealTimeSignum value) => this.Offset == value.Offset;
{
return lhs.Equals (rhs);
}
public static bool operator!= (RealTimeSignum lhs, RealTimeSignum rhs) public static Boolean operator ==(RealTimeSignum lhs, RealTimeSignum rhs) => lhs.Equals(rhs);
{
return !lhs.Equals (rhs); public static Boolean operator !=(RealTimeSignum lhs, RealTimeSignum rhs) => !lhs.Equals(rhs);
}
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,10 +28,12 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace Mono.Unix.Native { namespace Mono.Unix.Native {
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class blkcnt_tAttribute : MapAttribute { internal class blkcnt_tAttribute : MapAttribute {
public blkcnt_tAttribute () : base ("blkcnt_t") public blkcnt_tAttribute () : base ("blkcnt_t")
@ -40,6 +42,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class blksize_tAttribute : MapAttribute { internal class blksize_tAttribute : MapAttribute {
public blksize_tAttribute () : base ("blksize_t") public blksize_tAttribute () : base ("blksize_t")
@ -48,6 +51,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class dev_tAttribute : MapAttribute { internal class dev_tAttribute : MapAttribute {
public dev_tAttribute () : base ("dev_t") public dev_tAttribute () : base ("dev_t")
@ -56,6 +60,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class gid_tAttribute : MapAttribute { internal class gid_tAttribute : MapAttribute {
public gid_tAttribute () : base ("gid_t") public gid_tAttribute () : base ("gid_t")
@ -64,6 +69,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class fsblkcnt_tAttribute : MapAttribute { internal class fsblkcnt_tAttribute : MapAttribute {
public fsblkcnt_tAttribute () : base ("fsblkcnt_t") public fsblkcnt_tAttribute () : base ("fsblkcnt_t")
@ -72,6 +78,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class fsfilcnt_tAttribute : MapAttribute { internal class fsfilcnt_tAttribute : MapAttribute {
public fsfilcnt_tAttribute () : base ("fsfilcnt_t") public fsfilcnt_tAttribute () : base ("fsfilcnt_t")
@ -80,6 +87,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class ino_tAttribute : MapAttribute { internal class ino_tAttribute : MapAttribute {
public ino_tAttribute () : base ("ino_t") public ino_tAttribute () : base ("ino_t")
@ -88,6 +96,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class nlink_tAttribute : MapAttribute { internal class nlink_tAttribute : MapAttribute {
public nlink_tAttribute () : base ("nlink_t") public nlink_tAttribute () : base ("nlink_t")
@ -96,6 +105,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class off_tAttribute : MapAttribute { internal class off_tAttribute : MapAttribute {
public off_tAttribute () : base ("off_t") public off_tAttribute () : base ("off_t")
@ -104,6 +114,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class pid_tAttribute : MapAttribute { internal class pid_tAttribute : MapAttribute {
public pid_tAttribute () : base ("pid_t") public pid_tAttribute () : base ("pid_t")
@ -112,6 +123,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class suseconds_tAttribute : MapAttribute { internal class suseconds_tAttribute : MapAttribute {
public suseconds_tAttribute () : base ("suseconds_t") public suseconds_tAttribute () : base ("suseconds_t")
@ -120,6 +132,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
internal class uid_tAttribute : MapAttribute { internal class uid_tAttribute : MapAttribute {
public uid_tAttribute () : base ("uid_t") public uid_tAttribute () : base ("uid_t")
@ -128,6 +141,7 @@ namespace Mono.Unix.Native {
} }
[AttributeUsage (AttributeTargets.Field)] [AttributeUsage (AttributeTargets.Field)]
[SuppressMessage("Microsoft.Design","IDE1006", Justification = "Can not change name!")]
internal class time_tAttribute : MapAttribute { internal class time_tAttribute : MapAttribute {
public time_tAttribute () : base ("time_t") public time_tAttribute () : base ("time_t")

View File

@ -39,30 +39,27 @@ namespace Mono.Unix
[Serializable] [Serializable]
public class AbstractUnixEndPoint : EndPoint public class AbstractUnixEndPoint : EndPoint
{ {
string path; String path;
public AbstractUnixEndPoint (string path) public AbstractUnixEndPoint (String path)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
}
if (path == "") if (path == "") {
throw new ArgumentException ("Cannot be empty.", "path"); throw new ArgumentException ("Cannot be empty.", "path");
}
this.path = path; this.path = path;
} }
public string Path { public String Path {
get { get => this.path;
return(path); set => this.path = value;
}
set {
path=value;
}
} }
public override AddressFamily AddressFamily { public override AddressFamily AddressFamily => AddressFamily.Unix;
get { return AddressFamily.Unix; }
}
public override EndPoint Create (SocketAddress socketAddress) public override EndPoint Create (SocketAddress socketAddress)
{ {
@ -77,46 +74,43 @@ namespace Mono.Unix
throw new ArgumentException ("socketAddress is not a unix socket address."); throw new ArgumentException ("socketAddress is not a unix socket address.");
*/ */
byte [] bytes = new byte [socketAddress.Size - 2 - 1]; Byte[] bytes = new Byte[socketAddress.Size - 2 - 1];
for (int i = 0; i < bytes.Length; i++) { for (Int32 i = 0; i < bytes.Length; i++) {
bytes [i] = socketAddress [2 + 1 + i]; bytes [i] = socketAddress [2 + 1 + i];
} }
string name = Encoding.Default.GetString (bytes); String name = Encoding.Default.GetString (bytes);
return new AbstractUnixEndPoint (name); return new AbstractUnixEndPoint (name);
} }
public override SocketAddress Serialize () public override SocketAddress Serialize ()
{ {
byte [] bytes = Encoding.Default.GetBytes (path); Byte[] bytes = Encoding.Default.GetBytes (this.path);
SocketAddress sa = new SocketAddress (AddressFamily, 2 + 1 + bytes.Length); SocketAddress sa = new SocketAddress (this.AddressFamily, 2 + 1 + bytes.Length);
//NULL prefix denotes the abstract namespace, see unix(7) //NULL prefix denotes the abstract namespace, see unix(7)
//in this case, there is no NULL suffix //in this case, there is no NULL suffix
sa [2] = 0; sa [2] = 0;
// sa [0] -> family low byte, sa [1] -> family high byte // sa [0] -> family low byte, sa [1] -> family high byte
for (int i = 0; i < bytes.Length; i++) for (Int32 i = 0; i < bytes.Length; i++) {
sa [i + 2 + 1] = bytes [i]; sa [i + 2 + 1] = bytes [i];
}
return sa; return sa;
} }
public override string ToString() { public override String ToString() => this.path;
return(path);
}
public override int GetHashCode () public override Int32 GetHashCode() => this.path.GetHashCode();
{
return path.GetHashCode ();
}
public override bool Equals (object o) public override Boolean Equals (Object o)
{ {
AbstractUnixEndPoint other = o as AbstractUnixEndPoint; AbstractUnixEndPoint other = o as AbstractUnixEndPoint;
if (other == null) if (other == null) {
return false; return false;
}
return (other.path == path); return other.path == this.path;
} }
} }
} }

View File

@ -33,6 +33,7 @@
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Mono.Unix { namespace Mono.Unix {
@ -41,26 +42,33 @@ namespace Mono.Unix {
private Catalog () {} private Catalog () {}
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)] [DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname); static extern IntPtr bindtextdomain (IntPtr domainname, IntPtr dirname);
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)] [DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr bind_textdomain_codeset (IntPtr domainname, static extern IntPtr bind_textdomain_codeset (IntPtr domainname,
IntPtr codeset); IntPtr codeset);
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)] [DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr textdomain (IntPtr domainname); static extern IntPtr textdomain (IntPtr domainname);
public static void Init (String package, String localedir) public static void Init (String package, String localedir)
{ {
IntPtr ipackage, ilocaledir, iutf8; MarshalStrings(package, out IntPtr ipackage, localedir, out IntPtr ilocaledir,
MarshalStrings (package, out ipackage, localedir, out ilocaledir, "UTF-8", out IntPtr iutf8);
"UTF-8", out iutf8);
try { try {
if (bindtextdomain (ipackage, ilocaledir) == IntPtr.Zero) if (bindtextdomain (ipackage, ilocaledir) == IntPtr.Zero) {
throw new UnixIOException (Native.Errno.ENOMEM); throw new UnixIOException (Native.Errno.ENOMEM);
if (bind_textdomain_codeset (ipackage, iutf8) == IntPtr.Zero) }
if (bind_textdomain_codeset (ipackage, iutf8) == IntPtr.Zero) {
throw new UnixIOException (Native.Errno.ENOMEM); throw new UnixIOException (Native.Errno.ENOMEM);
if (textdomain (ipackage) == IntPtr.Zero) }
if (textdomain (ipackage) == IntPtr.Zero) {
throw new UnixIOException (Native.Errno.ENOMEM); throw new UnixIOException (Native.Errno.ENOMEM);
} }
}
finally { finally {
UnixMarshal.FreeHeap (ipackage); UnixMarshal.FreeHeap (ipackage);
UnixMarshal.FreeHeap (ilocaledir); UnixMarshal.FreeHeap (ilocaledir);
@ -68,18 +76,20 @@ namespace Mono.Unix {
} }
} }
private static void MarshalStrings (string s1, out IntPtr p1, private static void MarshalStrings (String s1, out IntPtr p1,
string s2, out IntPtr p2, string s3, out IntPtr p3) String s2, out IntPtr p2, String s3, out IntPtr p3)
{ {
p1 = p2 = p3 = IntPtr.Zero; p1 = p2 = p3 = IntPtr.Zero;
bool cleanup = true; Boolean cleanup = true;
try { try {
p1 = UnixMarshal.StringToHeap (s1); p1 = UnixMarshal.StringToHeap (s1);
p2 = UnixMarshal.StringToHeap (s2); p2 = UnixMarshal.StringToHeap (s2);
if (s3 != null) if (s3 != null) {
p3 = UnixMarshal.StringToHeap (s3); p3 = UnixMarshal.StringToHeap (s3);
}
cleanup = false; cleanup = false;
} }
finally { finally {
@ -92,6 +102,7 @@ namespace Mono.Unix {
} }
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)] [DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr gettext (IntPtr instring); static extern IntPtr gettext (IntPtr instring);
public static String GetString (String s) public static String GetString (String s)
@ -100,8 +111,10 @@ namespace Mono.Unix {
try { try {
// gettext(3) returns the input pointer if no translation is found // gettext(3) returns the input pointer if no translation is found
IntPtr r = gettext (ints); IntPtr r = gettext (ints);
if (r != ints) if (r != ints) {
return UnixMarshal.PtrToStringUnix (r); return UnixMarshal.PtrToStringUnix (r);
}
return s; return s;
} }
finally { finally {
@ -110,23 +123,18 @@ namespace Mono.Unix {
} }
[DllImport("intl", CallingConvention=CallingConvention.Cdecl)] [DllImport("intl", CallingConvention=CallingConvention.Cdecl)]
[SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n); static extern IntPtr ngettext (IntPtr singular, IntPtr plural, Int32 n);
public static String GetPluralString (String s, String p, Int32 n) public static String GetPluralString (String s, String p, Int32 n)
{ {
IntPtr ints, intp, _ignore; MarshalStrings(s, out IntPtr ints, p, out IntPtr intp, null, out IntPtr _ignore);
MarshalStrings (s, out ints, p, out intp, null, out _ignore);
try { try {
// ngettext(3) returns an input pointer if no translation is found // ngettext(3) returns an input pointer if no translation is found
IntPtr r = ngettext (ints, intp, n); IntPtr r = ngettext (ints, intp, n);
if (r == ints) return r == ints ? s : r == intp ? p : UnixMarshal.PtrToStringUnix (r);
return s; } finally {
if (r == intp)
return p;
return UnixMarshal.PtrToStringUnix (r);
}
finally {
UnixMarshal.FreeHeap (ints); UnixMarshal.FreeHeap (ints);
UnixMarshal.FreeHeap (intp); UnixMarshal.FreeHeap (intp);
} }

View File

@ -33,21 +33,21 @@ namespace Mono.Unix {
[Flags] [Flags]
public enum FileAccessPermissions { public enum FileAccessPermissions {
UserReadWriteExecute = (int) Native.FilePermissions.S_IRWXU, UserReadWriteExecute = (Int32) Native.FilePermissions.S_IRWXU,
UserRead = (int) Native.FilePermissions.S_IRUSR, UserRead = (Int32) Native.FilePermissions.S_IRUSR,
UserWrite = (int) Native.FilePermissions.S_IWUSR, UserWrite = (Int32) Native.FilePermissions.S_IWUSR,
UserExecute = (int) Native.FilePermissions.S_IXUSR, UserExecute = (Int32) Native.FilePermissions.S_IXUSR,
GroupReadWriteExecute = (int) Native.FilePermissions.S_IRWXG, GroupReadWriteExecute = (Int32) Native.FilePermissions.S_IRWXG,
GroupRead = (int) Native.FilePermissions.S_IRGRP, GroupRead = (Int32) Native.FilePermissions.S_IRGRP,
GroupWrite = (int) Native.FilePermissions.S_IWGRP, GroupWrite = (Int32) Native.FilePermissions.S_IWGRP,
GroupExecute = (int) Native.FilePermissions.S_IXGRP, GroupExecute = (Int32) Native.FilePermissions.S_IXGRP,
OtherReadWriteExecute = (int) Native.FilePermissions.S_IRWXO, OtherReadWriteExecute = (Int32) Native.FilePermissions.S_IRWXO,
OtherRead = (int) Native.FilePermissions.S_IROTH, OtherRead = (Int32) Native.FilePermissions.S_IROTH,
OtherWrite = (int) Native.FilePermissions.S_IWOTH, OtherWrite = (Int32) Native.FilePermissions.S_IWOTH,
OtherExecute = (int) Native.FilePermissions.S_IXOTH, OtherExecute = (Int32) Native.FilePermissions.S_IXOTH,
DefaultPermissions = (int) Native.FilePermissions.DEFFILEMODE, DefaultPermissions = (Int32) Native.FilePermissions.DEFFILEMODE,
AllPermissions = (int) Native.FilePermissions.ACCESSPERMS, AllPermissions = (Int32) Native.FilePermissions.ACCESSPERMS,
} }
} }

View File

@ -27,6 +27,7 @@
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Mono.Unix; using Mono.Unix;
@ -37,45 +38,41 @@ namespace Mono.Unix {
{ {
private FileHandleOperations () {} private FileHandleOperations () {}
public static void AdviseFileAccessPattern (int fd, FileAccessPattern pattern, long offset, long len) public static void AdviseFileAccessPattern (Int32 fd, FileAccessPattern pattern, Int64 offset, Int64 len)
{ {
int r = Native.Syscall.posix_fadvise (fd, offset, len, Int32 r = Native.Syscall.posix_fadvise (fd, offset, len,
(Native.PosixFadviseAdvice) pattern); (Native.PosixFadviseAdvice) pattern);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static void AdviseFileAccessPattern (int fd, FileAccessPattern pattern) public static void AdviseFileAccessPattern(Int32 fd, FileAccessPattern pattern) => AdviseFileAccessPattern(fd, pattern, 0, 0);
{
AdviseFileAccessPattern (fd, pattern, 0, 0);
}
public static void AdviseFileAccessPattern (FileStream file, FileAccessPattern pattern, long offset, long len) [SuppressMessage("Microsoft.Design", "CS0618", Justification = "Someone do shit")]
public static void AdviseFileAccessPattern (FileStream file, FileAccessPattern pattern, Int64 offset, Int64 len)
{ {
if (file == null) if (file == null) {
throw new ArgumentNullException ("file"); throw new ArgumentNullException ("file");
int r = Native.Syscall.posix_fadvise (file.Handle.ToInt32(), offset, len, }
Int32 r = Native.Syscall.posix_fadvise (file.Handle.ToInt32(), offset, len,
(Native.PosixFadviseAdvice) pattern); (Native.PosixFadviseAdvice) pattern);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static void AdviseFileAccessPattern (FileStream file, FileAccessPattern pattern) public static void AdviseFileAccessPattern(FileStream file, FileAccessPattern pattern) => AdviseFileAccessPattern(file, pattern, 0, 0);
{
AdviseFileAccessPattern (file, pattern, 0, 0);
}
public static void AdviseFileAccessPattern (UnixStream stream, FileAccessPattern pattern, long offset, long len) public static void AdviseFileAccessPattern (UnixStream stream, FileAccessPattern pattern, Int64 offset, Int64 len)
{ {
if (stream == null) if (stream == null) {
throw new ArgumentNullException ("stream"); throw new ArgumentNullException ("stream");
int r = Native.Syscall.posix_fadvise (stream.Handle, offset, len, }
Int32 r = Native.Syscall.posix_fadvise (stream.Handle, offset, len,
(Native.PosixFadviseAdvice) pattern); (Native.PosixFadviseAdvice) pattern);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static void AdviseFileAccessPattern (UnixStream stream, FileAccessPattern pattern) public static void AdviseFileAccessPattern(UnixStream stream, FileAccessPattern pattern) => AdviseFileAccessPattern(stream, pattern, 0, 0);
{
AdviseFileAccessPattern (stream, pattern, 0, 0);
}
} }
} }

View File

@ -33,9 +33,9 @@ namespace Mono.Unix {
[Flags] [Flags]
public enum FileSpecialAttributes { public enum FileSpecialAttributes {
SetUserId = (int) Native.FilePermissions.S_ISUID, SetUserId = (Int32) Native.FilePermissions.S_ISUID,
SetGroupId = (int) Native.FilePermissions.S_ISGID, SetGroupId = (Int32) Native.FilePermissions.S_ISGID,
Sticky = (int) Native.FilePermissions.S_ISVTX, Sticky = (Int32) Native.FilePermissions.S_ISVTX,
} }
} }

View File

@ -32,13 +32,14 @@ using Mono.Unix;
namespace Mono.Unix { namespace Mono.Unix {
public enum FileTypes { public enum FileTypes {
Directory = (int) Native.FilePermissions.S_IFDIR, Directory = (Int32) Native.FilePermissions.S_IFDIR,
CharacterDevice = (int) Native.FilePermissions.S_IFCHR, CharacterDevice = (Int32) Native.FilePermissions.S_IFCHR,
BlockDevice = (int) Native.FilePermissions.S_IFBLK, BlockDevice = (Int32) Native.FilePermissions.S_IFBLK,
RegularFile = (int) Native.FilePermissions.S_IFREG, RegularFile = (Int32) Native.FilePermissions.S_IFREG,
Fifo = (int) Native.FilePermissions.S_IFIFO, Fifo = (Int32) Native.FilePermissions.S_IFIFO,
SymbolicLink = (int) Native.FilePermissions.S_IFLNK, SymbolicLink = (Int32) Native.FilePermissions.S_IFLNK,
Socket = (int) Native.FilePermissions.S_IFSOCK, Socket = (Int32) Native.FilePermissions.S_IFSOCK,
} }
} }

View File

@ -35,9 +35,9 @@ namespace Mono.Unix
{ {
#pragma warning disable 649 #pragma warning disable 649
internal struct PeerCredData { internal struct PeerCredData {
public int pid; public Int32 pid;
public int uid; public Int32 uid;
public int gid; public Int32 gid;
} }
#pragma warning restore 649 #pragma warning restore 649
@ -47,7 +47,7 @@ namespace Mono.Unix
* SocketOptionName, and keep it synchronised with the * SocketOptionName, and keep it synchronised with the
* runtime * runtime
*/ */
private const int so_peercred=10001; private const Int32 so_peercred =10001;
private PeerCredData data; private PeerCredData data;
public PeerCred (Socket sock) { public PeerCred (Socket sock) {
@ -55,27 +55,15 @@ namespace Mono.Unix
throw new ArgumentException ("Only Unix sockets are supported", "sock"); throw new ArgumentException ("Only Unix sockets are supported", "sock");
} }
data = (PeerCredData) this.data = (PeerCredData)
sock.GetSocketOption (SocketOptionLevel.Socket, (SocketOptionName)so_peercred); sock.GetSocketOption (SocketOptionLevel.Socket, (SocketOptionName)so_peercred);
} }
public int ProcessID { public Int32 ProcessID => this.data.pid;
get {
return(data.pid);
}
}
public int UserID { public Int32 UserID => this.data.uid;
get {
return(data.uid);
}
}
public int GroupID { public Int32 GroupID => this.data.gid;
get {
return(data.gid);
}
}
} }
} }

View File

@ -44,89 +44,109 @@ namespace Mono.Unix {
public StdioFileStream (IntPtr fileStream) public StdioFileStream (IntPtr fileStream)
: this (fileStream, true) {} : this (fileStream, true) {}
public StdioFileStream (IntPtr fileStream, bool ownsHandle) public StdioFileStream(IntPtr fileStream, Boolean ownsHandle) => this.InitStream(fileStream, ownsHandle);
{
InitStream (fileStream, ownsHandle);
}
public StdioFileStream (IntPtr fileStream, FileAccess access) public StdioFileStream (IntPtr fileStream, FileAccess access)
: this (fileStream, access, true) {} : this (fileStream, access, true) {}
public StdioFileStream (IntPtr fileStream, FileAccess access, bool ownsHandle) public StdioFileStream (IntPtr fileStream, FileAccess access, Boolean ownsHandle)
{ {
InitStream (fileStream, ownsHandle); this.InitStream (fileStream, ownsHandle);
InitCanReadWrite (access); this.InitCanReadWrite (access);
} }
public StdioFileStream (string path) public StdioFileStream (String path)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
InitStream (Fopen (path, "rb"), true);
} }
public StdioFileStream (string path, string mode) this.InitStream (Fopen (path, "rb"), true);
}
public StdioFileStream (String path, String mode)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
InitStream (Fopen (path, mode), true);
} }
public StdioFileStream (string path, FileMode mode) this.InitStream (Fopen (path, mode), true);
}
public StdioFileStream (String path, FileMode mode)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
InitStream (Fopen (path, ToFopenMode (path, mode)), true);
} }
public StdioFileStream (string path, FileAccess access) this.InitStream (Fopen (path, ToFopenMode (path, mode)), true);
}
public StdioFileStream (String path, FileAccess access)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
InitStream (Fopen (path, ToFopenMode (path, access)), true);
InitCanReadWrite (access);
} }
public StdioFileStream (string path, FileMode mode, FileAccess access) this.InitStream (Fopen (path, ToFopenMode (path, access)), true);
this.InitCanReadWrite (access);
}
public StdioFileStream (String path, FileMode mode, FileAccess access)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
InitStream (Fopen (path, ToFopenMode (path, mode, access)), true);
InitCanReadWrite (access);
} }
private static IntPtr Fopen (string path, string mode) this.InitStream (Fopen (path, ToFopenMode (path, mode, access)), true);
this.InitCanReadWrite (access);
}
private static IntPtr Fopen (String path, String mode)
{ {
if (path.Length == 0) if (path.Length == 0) {
throw new ArgumentException ("path"); throw new ArgumentException ("path");
if (mode == null) }
if (mode == null) {
throw new ArgumentNullException ("mode"); throw new ArgumentNullException ("mode");
}
IntPtr f = Native.Stdlib.fopen (path, mode); IntPtr f = Native.Stdlib.fopen (path, mode);
if (f == IntPtr.Zero) if (f == IntPtr.Zero) {
throw new DirectoryNotFoundException ("path", throw new DirectoryNotFoundException ("path",
UnixMarshal.CreateExceptionForLastError ()); UnixMarshal.CreateExceptionForLastError ());
}
return f; return f;
} }
private void InitStream (IntPtr fileStream, bool ownsHandle) private void InitStream (IntPtr fileStream, Boolean ownsHandle)
{ {
if (InvalidFileStream == fileStream) if (InvalidFileStream == fileStream) {
throw new ArgumentException (Locale.GetText ("Invalid file stream"), "fileStream"); throw new ArgumentException (Locale.GetText ("Invalid file stream"), "fileStream");
}
this.file = fileStream; this.file = fileStream;
this.owner = ownsHandle; this.owner = ownsHandle;
try { try {
long offset = Native.Stdlib.fseek (file, 0, Native.SeekFlags.SEEK_CUR); Int64 offset = Native.Stdlib.fseek (this.file, 0, Native.SeekFlags.SEEK_CUR);
if (offset != -1) if (offset != -1) {
canSeek = true; this.canSeek = true;
Native.Stdlib.fread (IntPtr.Zero, 0, 0, file); }
if (Native.Stdlib.ferror (file) == 0)
canRead = true; _ = Native.Stdlib.fread(IntPtr.Zero, 0, 0, this.file);
Native.Stdlib.fwrite (IntPtr.Zero, 0, 0, file); if (Native.Stdlib.ferror (this.file) == 0) {
if (Native.Stdlib.ferror (file) == 0) this.canRead = true;
canWrite = true; }
Native.Stdlib.clearerr (file);
_ = Native.Stdlib.fwrite(IntPtr.Zero, 0, 0, this.file);
if (Native.Stdlib.ferror (this.file) == 0) {
this.canWrite = true;
}
_ = Native.Stdlib.clearerr(this.file);
} }
catch (Exception) { catch (Exception) {
throw new ArgumentException (Locale.GetText ("Invalid file stream"), "fileStream"); throw new ArgumentException (Locale.GetText ("Invalid file stream"), "fileStream");
@ -136,99 +156,105 @@ namespace Mono.Unix {
private void InitCanReadWrite (FileAccess access) private void InitCanReadWrite (FileAccess access)
{ {
canRead = canRead && this.canRead = this.canRead &&
(access == FileAccess.Read || access == FileAccess.ReadWrite); (access == FileAccess.Read || access == FileAccess.ReadWrite);
canWrite = canWrite && this.canWrite = this.canWrite &&
(access == FileAccess.Write || access == FileAccess.ReadWrite); (access == FileAccess.Write || access == FileAccess.ReadWrite);
} }
private static string ToFopenMode (string file, FileMode mode) private static String ToFopenMode (String file, FileMode mode)
{ {
string cmode = Native.NativeConvert.ToFopenMode (mode); String cmode = Native.NativeConvert.ToFopenMode (mode);
AssertFileMode (file, mode); _ = AssertFileMode(file, mode);
return cmode; return cmode;
} }
private static string ToFopenMode (string file, FileAccess access) private static String ToFopenMode(String file, FileAccess access) => Native.NativeConvert.ToFopenMode(access);
{
return Native.NativeConvert.ToFopenMode (access);
}
private static string ToFopenMode (string file, FileMode mode, FileAccess access) private static String ToFopenMode (String file, FileMode mode, FileAccess access)
{ {
string cmode = Native.NativeConvert.ToFopenMode (mode, access); String cmode = Native.NativeConvert.ToFopenMode (mode, access);
bool exists = AssertFileMode (file, mode); Boolean exists = AssertFileMode (file, mode);
// HACK: for open-or-create & read, mode is "rb", which doesn't create // HACK: for open-or-create & read, mode is "rb", which doesn't create
// files. If the file doesn't exist, we need to use "w+b" to ensure // files. If the file doesn't exist, we need to use "w+b" to ensure
// file creation. // file creation.
if (mode == FileMode.OpenOrCreate && access == FileAccess.Read && !exists) if (mode == FileMode.OpenOrCreate && access == FileAccess.Read && !exists) {
cmode = "w+b"; cmode = "w+b";
}
return cmode; return cmode;
} }
private static bool AssertFileMode (string file, FileMode mode) private static Boolean AssertFileMode (String file, FileMode mode)
{ {
bool exists = FileExists (file); Boolean exists = FileExists (file);
if (mode == FileMode.CreateNew && exists) if (mode == FileMode.CreateNew && exists) {
throw new IOException ("File exists and FileMode.CreateNew specified"); throw new IOException ("File exists and FileMode.CreateNew specified");
if ((mode == FileMode.Open || mode == FileMode.Truncate) && !exists) }
if ((mode == FileMode.Open || mode == FileMode.Truncate) && !exists) {
throw new FileNotFoundException ("File doesn't exist and FileMode.Open specified", file); throw new FileNotFoundException ("File doesn't exist and FileMode.Open specified", file);
}
return exists; return exists;
} }
private static bool FileExists (string file) private static Boolean FileExists (String file)
{ {
bool found = false; Boolean found = false;
IntPtr f = Native.Stdlib.fopen (file, "r"); IntPtr f = Native.Stdlib.fopen (file, "r");
found = f != IntPtr.Zero; found = f != IntPtr.Zero;
if (f != IntPtr.Zero) if (f != IntPtr.Zero) {
Native.Stdlib.fclose (f); _ = Native.Stdlib.fclose(f);
}
return found; return found;
} }
private void AssertNotDisposed () private void AssertNotDisposed ()
{ {
if (file == InvalidFileStream) if (this.file == InvalidFileStream) {
throw new ObjectDisposedException ("Invalid File Stream"); throw new ObjectDisposedException ("Invalid File Stream");
}
GC.KeepAlive (this); GC.KeepAlive (this);
} }
public IntPtr Handle { public IntPtr Handle {
get { get {
AssertNotDisposed (); this.AssertNotDisposed ();
GC.KeepAlive (this); GC.KeepAlive (this);
return file; return this.file;
} }
} }
public override bool CanRead { public override Boolean CanRead => this.canRead;
get {return canRead;}
}
public override bool CanSeek { public override Boolean CanSeek => this.canSeek;
get {return canSeek;}
}
public override bool CanWrite { public override Boolean CanWrite => this.canWrite;
get {return canWrite;}
}
public override long Length { public override Int64 Length {
get { get {
AssertNotDisposed (); this.AssertNotDisposed ();
if (!CanSeek) if (!this.CanSeek) {
throw new NotSupportedException ("File Stream doesn't support seeking"); throw new NotSupportedException ("File Stream doesn't support seeking");
long curPos = Native.Stdlib.ftell (file); }
if (curPos == -1)
Int64 curPos = Native.Stdlib.ftell (this.file);
if (curPos == -1) {
throw new NotSupportedException ("Unable to obtain current file position"); throw new NotSupportedException ("Unable to obtain current file position");
int r = Native.Stdlib.fseek (file, 0, Native.SeekFlags.SEEK_END); }
Int32 r = Native.Stdlib.fseek (this.file, 0, Native.SeekFlags.SEEK_END);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
long endPos = Native.Stdlib.ftell (file); Int64 endPos = Native.Stdlib.ftell (this.file);
if (endPos == -1) if (endPos == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
r = Native.Stdlib.fseek (file, curPos, Native.SeekFlags.SEEK_SET); r = Native.Stdlib.fseek (this.file, curPos, Native.SeekFlags.SEEK_SET);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
GC.KeepAlive (this); GC.KeepAlive (this);
@ -236,95 +262,115 @@ namespace Mono.Unix {
} }
} }
public override long Position { public override Int64 Position {
get { get {
AssertNotDisposed (); this.AssertNotDisposed ();
if (!CanSeek) if (!this.CanSeek) {
throw new NotSupportedException ("The stream does not support seeking"); throw new NotSupportedException ("The stream does not support seeking");
long pos = Native.Stdlib.ftell (file); }
if (pos == -1)
Int64 pos = Native.Stdlib.ftell (this.file);
if (pos == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
GC.KeepAlive (this); GC.KeepAlive (this);
return (long) pos; return (Int64) pos;
} }
set { set {
AssertNotDisposed (); this.AssertNotDisposed ();
Seek (value, SeekOrigin.Begin); _ = this.Seek(value, SeekOrigin.Begin);
} }
} }
public void SaveFilePosition (Native.FilePosition pos) public void SaveFilePosition (Native.FilePosition pos)
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
int r = Native.Stdlib.fgetpos (file, pos); Int32 r = Native.Stdlib.fgetpos (this.file, pos);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
GC.KeepAlive (this); GC.KeepAlive (this);
} }
public void RestoreFilePosition (Native.FilePosition pos) public void RestoreFilePosition (Native.FilePosition pos)
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
if (pos == null) if (pos == null) {
throw new ArgumentNullException ("value"); throw new ArgumentNullException ("value");
int r = Native.Stdlib.fsetpos (file, pos); }
Int32 r = Native.Stdlib.fsetpos (this.file, pos);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
GC.KeepAlive (this); GC.KeepAlive (this);
} }
public override void Flush () public override void Flush ()
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
int r = Native.Stdlib.fflush (file); Int32 r = Native.Stdlib.fflush (this.file);
if (r != 0) if (r != 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
GC.KeepAlive (this); GC.KeepAlive (this);
} }
public override unsafe int Read ([In, Out] byte[] buffer, int offset, int count) public override unsafe Int32 Read ([In, Out] Byte[] buffer, Int32 offset, Int32 count)
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
AssertValidBuffer (buffer, offset, count); this.AssertValidBuffer (buffer, offset, count);
if (!CanRead) if (!this.CanRead) {
throw new NotSupportedException ("Stream does not support reading"); throw new NotSupportedException ("Stream does not support reading");
ulong r = 0;
fixed (byte* buf = &buffer[offset]) {
r = Native.Stdlib.fread (buf, 1, (ulong) count, file);
} }
if (r != (ulong) count) {
if (Native.Stdlib.ferror (file) != 0) UInt64 r = 0;
fixed (Byte* buf = &buffer[offset]) {
r = Native.Stdlib.fread (buf, 1, (UInt64) count, this.file);
}
if (r != (UInt64) count) {
if (Native.Stdlib.ferror (this.file) != 0) {
throw new IOException (); throw new IOException ();
} }
}
GC.KeepAlive (this); GC.KeepAlive (this);
return (int) r; return (Int32) r;
} }
private void AssertValidBuffer (byte[] buffer, int offset, int count) private void AssertValidBuffer (Byte[] buffer, Int32 offset, Int32 count)
{ {
if (buffer == null) if (buffer == null) {
throw new ArgumentNullException ("buffer"); throw new ArgumentNullException ("buffer");
if (offset < 0) }
if (offset < 0) {
throw new ArgumentOutOfRangeException ("offset", "< 0"); throw new ArgumentOutOfRangeException ("offset", "< 0");
if (count < 0) }
if (count < 0) {
throw new ArgumentOutOfRangeException ("count", "< 0"); throw new ArgumentOutOfRangeException ("count", "< 0");
if (offset > buffer.Length) }
if (offset > buffer.Length) {
throw new ArgumentException ("destination offset is beyond array size"); throw new ArgumentException ("destination offset is beyond array size");
if (offset > (buffer.Length - count)) }
if (offset > buffer.Length - count) {
throw new ArgumentException ("would overrun buffer"); throw new ArgumentException ("would overrun buffer");
} }
}
public void Rewind () public void Rewind ()
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
Native.Stdlib.rewind (file); _ = Native.Stdlib.rewind(this.file);
GC.KeepAlive (this); GC.KeepAlive (this);
} }
public override long Seek (long offset, SeekOrigin origin) public override Int64 Seek (Int64 offset, SeekOrigin origin)
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
if (!CanSeek) if (!this.CanSeek) {
throw new NotSupportedException ("The File Stream does not support seeking"); throw new NotSupportedException ("The File Stream does not support seeking");
}
Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR; Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR;
switch (origin) { switch (origin) {
@ -334,71 +380,76 @@ namespace Mono.Unix {
default: throw new ArgumentException ("origin"); default: throw new ArgumentException ("origin");
} }
int r = Native.Stdlib.fseek (file, offset, sf); Int32 r = Native.Stdlib.fseek (this.file, offset, sf);
if (r != 0) if (r != 0) {
throw new IOException ("Unable to seek", throw new IOException ("Unable to seek",
UnixMarshal.CreateExceptionForLastError ()); UnixMarshal.CreateExceptionForLastError ());
}
long pos = Native.Stdlib.ftell (file); Int64 pos = Native.Stdlib.ftell (this.file);
if (pos == -1) if (pos == -1) {
throw new IOException ("Unable to get current file position", throw new IOException ("Unable to get current file position",
UnixMarshal.CreateExceptionForLastError ()); UnixMarshal.CreateExceptionForLastError ());
}
GC.KeepAlive (this); GC.KeepAlive (this);
return pos; return pos;
} }
public override void SetLength (long value) public override void SetLength(Int64 value) => throw new NotSupportedException("ANSI C doesn't provide a way to truncate a file");
{
throw new NotSupportedException ("ANSI C doesn't provide a way to truncate a file");
}
public override unsafe void Write (byte[] buffer, int offset, int count) public override unsafe void Write (Byte[] buffer, Int32 offset, Int32 count)
{ {
AssertNotDisposed (); this.AssertNotDisposed ();
AssertValidBuffer (buffer, offset, count); this.AssertValidBuffer (buffer, offset, count);
if (!CanWrite) if (!this.CanWrite) {
throw new NotSupportedException ("File Stream does not support writing"); throw new NotSupportedException ("File Stream does not support writing");
ulong r = 0;
fixed (byte* buf = &buffer[offset]) {
r = Native.Stdlib.fwrite (buf, (ulong) 1, (ulong) count, file);
} }
if (r != (ulong) count)
UInt64 r = 0;
fixed (Byte* buf = &buffer[offset]) {
r = Native.Stdlib.fwrite (buf, (UInt64) 1, (UInt64) count, this.file);
}
if (r != (UInt64) count) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
GC.KeepAlive (this); GC.KeepAlive (this);
} }
~StdioFileStream () ~StdioFileStream ()
{ {
Close (); this.Close ();
} }
public override void Close () public override void Close ()
{ {
if (file == InvalidFileStream) if (this.file == InvalidFileStream) {
return; return;
}
if (owner) { if (this.owner) {
int r = Native.Stdlib.fclose (file); Int32 r = Native.Stdlib.fclose (this.file);
if (r != 0) if (r != 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
} else }
Flush (); } else {
this.Flush ();
}
file = InvalidFileStream; this.file = InvalidFileStream;
canRead = false; this.canRead = false;
canSeek = false; this.canSeek = false;
canWrite = false; this.canWrite = false;
GC.SuppressFinalize (this); GC.SuppressFinalize (this);
GC.KeepAlive (this); GC.KeepAlive (this);
} }
private bool canSeek = false; private Boolean canSeek = false;
private bool canRead = false; private Boolean canRead = false;
private bool canWrite = false; private Boolean canWrite = false;
private bool owner = true; private Boolean owner = true;
private IntPtr file = InvalidFileStream; private IntPtr file = InvalidFileStream;
} }
} }

View File

@ -38,192 +38,194 @@ namespace Mono.Unix {
public class UnixClient : MarshalByRefObject, IDisposable { public class UnixClient : MarshalByRefObject, IDisposable {
NetworkStream stream; NetworkStream stream;
Socket client; Socket client;
bool disposed; Boolean disposed;
public UnixClient () public UnixClient ()
{ {
if (client != null) { if (this.client != null) {
client.Close (); this.client.Close ();
client = null; this.client = null;
} }
client = new Socket (AddressFamily.Unix, SocketType.Stream, 0); this.client = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
} }
public UnixClient (string path) : this () public UnixClient (String path) : this ()
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("ep"); throw new ArgumentNullException ("ep");
}
Connect (path); this.Connect (path);
} }
public UnixClient (UnixEndPoint ep) : this () public UnixClient (UnixEndPoint ep) : this ()
{ {
if (ep == null) if (ep == null) {
throw new ArgumentNullException ("ep"); throw new ArgumentNullException ("ep");
}
Connect (ep); this.Connect (ep);
} }
// UnixListener uses this when accepting a connection. // UnixListener uses this when accepting a connection.
internal UnixClient (Socket sock) internal UnixClient(Socket sock) => this.Client = sock;
{
Client = sock;
}
public public
Socket Client { Socket Client {
get { return client; } get => this.client;
set { set {
client = value; this.client = value;
stream = null; this.stream = null;
} }
} }
public PeerCred PeerCredential { public PeerCred PeerCredential {
get { get {
CheckDisposed (); this.CheckDisposed ();
return new PeerCred (client); return new PeerCred (this.client);
} }
} }
public LingerOption LingerState { public LingerOption LingerState {
get { get {
CheckDisposed (); this.CheckDisposed ();
return (LingerOption) client.GetSocketOption (SocketOptionLevel.Socket, return (LingerOption)this.client.GetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.Linger); SocketOptionName.Linger);
} }
set { set {
CheckDisposed (); this.CheckDisposed ();
client.SetSocketOption (SocketOptionLevel.Socket, this.client.SetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.Linger, value); SocketOptionName.Linger, value);
} }
} }
public int ReceiveBufferSize { public Int32 ReceiveBufferSize {
get { get {
CheckDisposed (); this.CheckDisposed ();
return (int) client.GetSocketOption (SocketOptionLevel.Socket, return (Int32)this.client.GetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.ReceiveBuffer); SocketOptionName.ReceiveBuffer);
} }
set { set {
CheckDisposed (); this.CheckDisposed ();
client.SetSocketOption (SocketOptionLevel.Socket, this.client.SetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.ReceiveBuffer, value); SocketOptionName.ReceiveBuffer, value);
} }
} }
public int ReceiveTimeout { public Int32 ReceiveTimeout {
get { get {
CheckDisposed (); this.CheckDisposed ();
return (int) client.GetSocketOption (SocketOptionLevel.Socket, return (Int32)this.client.GetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout); SocketOptionName.ReceiveTimeout);
} }
set { set {
CheckDisposed (); this.CheckDisposed ();
client.SetSocketOption (SocketOptionLevel.Socket, this.client.SetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, value); SocketOptionName.ReceiveTimeout, value);
} }
} }
public int SendBufferSize { public Int32 SendBufferSize {
get { get {
CheckDisposed (); this.CheckDisposed ();
return (int) client.GetSocketOption (SocketOptionLevel.Socket, return (Int32)this.client.GetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.SendBuffer); SocketOptionName.SendBuffer);
} }
set { set {
CheckDisposed (); this.CheckDisposed ();
client.SetSocketOption (SocketOptionLevel.Socket, this.client.SetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.SendBuffer, value); SocketOptionName.SendBuffer, value);
} }
} }
public int SendTimeout { public Int32 SendTimeout {
get { get {
CheckDisposed (); this.CheckDisposed ();
return (int) client.GetSocketOption (SocketOptionLevel.Socket, return (Int32)this.client.GetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.SendTimeout); SocketOptionName.SendTimeout);
} }
set { set {
CheckDisposed (); this.CheckDisposed ();
client.SetSocketOption (SocketOptionLevel.Socket, this.client.SetSocketOption (SocketOptionLevel.Socket,
SocketOptionName.SendTimeout, value); SocketOptionName.SendTimeout, value);
} }
} }
public void Close () public void Close ()
{ {
CheckDisposed (); this.CheckDisposed ();
Dispose (); this.Dispose ();
} }
public void Connect (UnixEndPoint remoteEndPoint) public void Connect (UnixEndPoint remoteEndPoint)
{ {
CheckDisposed (); this.CheckDisposed ();
client.Connect (remoteEndPoint); this.client.Connect (remoteEndPoint);
stream = new NetworkStream (client, true); this.stream = new NetworkStream (this.client, true);
} }
public void Connect (string path) public void Connect (String path)
{ {
CheckDisposed (); this.CheckDisposed ();
Connect (new UnixEndPoint (path)); this.Connect (new UnixEndPoint (path));
} }
public void Dispose () public void Dispose ()
{ {
Dispose (true); this.Dispose (true);
GC.SuppressFinalize (this); GC.SuppressFinalize (this);
} }
protected virtual void Dispose (bool disposing) protected virtual void Dispose (Boolean disposing)
{ {
if (disposed) if (this.disposed) {
return; return;
}
if (disposing) { if (disposing) {
// release managed resources // release managed resources
NetworkStream s = stream; NetworkStream s = this.stream;
stream = null; this.stream = null;
if (s != null) { if (s != null) {
// This closes the socket as well, as the NetworkStream // This closes the socket as well, as the NetworkStream
// owns the socket. // owns the socket.
s.Close(); s.Close();
s = null; s = null;
} else if (client != null){ } else if (this.client != null){
client.Close (); this.client.Close ();
} }
client = null; this.client = null;
} }
disposed = true; this.disposed = true;
} }
public NetworkStream GetStream () public NetworkStream GetStream ()
{ {
CheckDisposed (); this.CheckDisposed ();
if (stream == null) if (this.stream == null) {
stream = new NetworkStream (client, true); this.stream = new NetworkStream (this.client, true);
}
return stream; return this.stream;
} }
void CheckDisposed () void CheckDisposed ()
{ {
if (disposed) if (this.disposed) {
throw new ObjectDisposedException (GetType().FullName); throw new ObjectDisposedException (this.GetType().FullName);
}
} }
~UnixClient () ~UnixClient ()
{ {
Dispose (false); this.Dispose (false);
} }
} }
} }

View File

@ -37,137 +37,138 @@ namespace Mono.Unix {
public sealed class UnixDirectoryInfo : UnixFileSystemInfo public sealed class UnixDirectoryInfo : UnixFileSystemInfo
{ {
public UnixDirectoryInfo (string path) public UnixDirectoryInfo (String path)
: base (path) : base (path)
{ {
} }
internal UnixDirectoryInfo (string path, Native.Stat stat) internal UnixDirectoryInfo (String path, Native.Stat stat)
: base (path, stat) : base (path, stat)
{ {
} }
public override string Name { public override String Name {
get { get {
string r = UnixPath.GetFileName (FullPath); String r = UnixPath.GetFileName (this.FullPath);
if (r == null || r.Length == 0) return r == null || r.Length == 0 ? this.FullPath : r;
return FullPath;
return r;
} }
} }
public UnixDirectoryInfo Parent { public UnixDirectoryInfo Parent {
get { get {
if (FullPath == "/") if (this.FullPath == "/") {
return this; return this;
string dirname = UnixPath.GetDirectoryName (FullPath); }
if (dirname == "")
throw new InvalidOperationException ("Do not know parent directory for path `" + FullPath + "'"); String dirname = UnixPath.GetDirectoryName (this.FullPath);
if (dirname == "") {
throw new InvalidOperationException ("Do not know parent directory for path `" + this.FullPath + "'");
}
return new UnixDirectoryInfo (dirname); return new UnixDirectoryInfo (dirname);
} }
} }
public UnixDirectoryInfo Root { public UnixDirectoryInfo Root {
get { get {
string root = UnixPath.GetPathRoot (FullPath); String root = UnixPath.GetPathRoot (this.FullPath);
if (root == null) return root == null ? null : new UnixDirectoryInfo (root);
return null;
return new UnixDirectoryInfo (root);
} }
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public void Create (Mono.Unix.Native.FilePermissions mode) public void Create (Mono.Unix.Native.FilePermissions mode)
{ {
int r = Mono.Unix.Native.Syscall.mkdir (FullPath, mode); Int32 r = Mono.Unix.Native.Syscall.mkdir (this.FullPath, mode);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
base.Refresh (); base.Refresh ();
} }
public void Create (FileAccessPermissions mode) public void Create(FileAccessPermissions mode) => this.Create((Native.FilePermissions)mode);
{
Create ((Native.FilePermissions) mode);
}
public void Create () public void Create ()
{ {
Mono.Unix.Native.FilePermissions mode = Mono.Unix.Native.FilePermissions mode =
Mono.Unix.Native.FilePermissions.ACCESSPERMS; Mono.Unix.Native.FilePermissions.ACCESSPERMS;
Create (mode); this.Create (mode);
} }
public override void Delete () public override void Delete() => this.Delete(false);
{
Delete (false);
}
public void Delete (bool recursive) public void Delete (Boolean recursive)
{ {
if (recursive) { if (recursive) {
foreach (UnixFileSystemInfo e in GetFileSystemEntries ()) { foreach (UnixFileSystemInfo e in this.GetFileSystemEntries ()) {
UnixDirectoryInfo d = e as UnixDirectoryInfo; UnixDirectoryInfo d = e as UnixDirectoryInfo;
if (d != null) if (d != null) {
d.Delete (true); d.Delete (true);
else } else {
e.Delete (); e.Delete ();
} }
} }
int r = Native.Syscall.rmdir (FullPath); }
Int32 r = Native.Syscall.rmdir (this.FullPath);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
base.Refresh (); base.Refresh ();
} }
public Native.Dirent[] GetEntries () public Native.Dirent[] GetEntries ()
{ {
IntPtr dirp = Native.Syscall.opendir (FullPath); IntPtr dirp = Native.Syscall.opendir (this.FullPath);
if (dirp == IntPtr.Zero) if (dirp == IntPtr.Zero) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
bool complete = false; Boolean complete = false;
try { try {
Native.Dirent[] entries = GetEntries (dirp); Native.Dirent[] entries = GetEntries (dirp);
complete = true; complete = true;
return entries; return entries;
} }
finally { finally {
int r = Native.Syscall.closedir (dirp); Int32 r = Native.Syscall.closedir (dirp);
// don't throw an exception if an exception is in progress // don't throw an exception if an exception is in progress
if (complete) if (complete) {
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
} }
}
private static Native.Dirent[] GetEntries (IntPtr dirp) private static Native.Dirent[] GetEntries (IntPtr dirp)
{ {
ArrayList entries = new ArrayList (); ArrayList entries = new ArrayList ();
int r; Int32 r;
IntPtr result; IntPtr result;
do { do {
Native.Dirent d = new Native.Dirent (); Native.Dirent d = new Native.Dirent ();
r = Native.Syscall.readdir_r (dirp, d, out result); r = Native.Syscall.readdir_r (dirp, d, out result);
if (r == 0 && result != IntPtr.Zero) if (r == 0 && result != IntPtr.Zero) {
// don't include current & parent dirs // don't include current & parent dirs
if (d.d_name != "." && d.d_name != "..") if (d.d_name != "." && d.d_name != "..") {
entries.Add (d); _ = entries.Add(d);
}
}
} while (r == 0 && result != IntPtr.Zero); } while (r == 0 && result != IntPtr.Zero);
if (r != 0) if (r != 0) {
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent)); return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent));
} }
public Native.Dirent[] GetEntries (Regex regex) public Native.Dirent[] GetEntries (Regex regex)
{ {
IntPtr dirp = Native.Syscall.opendir (FullPath); IntPtr dirp = Native.Syscall.opendir (this.FullPath);
if (dirp == IntPtr.Zero) if (dirp == IntPtr.Zero) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
try { try {
return GetEntries (dirp, regex); return GetEntries (dirp, regex);
} }
finally { finally {
int r = Native.Syscall.closedir (dirp); Int32 r = Native.Syscall.closedir (dirp);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
} }
@ -176,72 +177,78 @@ namespace Mono.Unix {
{ {
ArrayList entries = new ArrayList (); ArrayList entries = new ArrayList ();
int r; Int32 r;
IntPtr result; IntPtr result;
do { do {
Native.Dirent d = new Native.Dirent (); Native.Dirent d = new Native.Dirent ();
r = Native.Syscall.readdir_r (dirp, d, out result); r = Native.Syscall.readdir_r (dirp, d, out result);
if (r == 0 && result != IntPtr.Zero && regex.Match (d.d_name).Success) { if (r == 0 && result != IntPtr.Zero && regex.Match (d.d_name).Success) {
// don't include current & parent dirs // don't include current & parent dirs
if (d.d_name != "." && d.d_name != "..") if (d.d_name != "." && d.d_name != "..") {
entries.Add (d); _ = entries.Add(d);
}
} }
} while (r == 0 && result != IntPtr.Zero); } while (r == 0 && result != IntPtr.Zero);
if (r != 0) if (r != 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent)); return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent));
} }
public Native.Dirent[] GetEntries (string regex) public Native.Dirent[] GetEntries (String regex)
{ {
Regex re = new Regex (regex); Regex re = new Regex (regex);
return GetEntries (re); return this.GetEntries (re);
} }
public UnixFileSystemInfo[] GetFileSystemEntries () public UnixFileSystemInfo[] GetFileSystemEntries ()
{ {
Native.Dirent[] dentries = GetEntries (); Native.Dirent[] dentries = this.GetEntries ();
return GetFileSystemEntries (dentries); return this.GetFileSystemEntries (dentries);
} }
private UnixFileSystemInfo[] GetFileSystemEntries (Native.Dirent[] dentries) private UnixFileSystemInfo[] GetFileSystemEntries (Native.Dirent[] dentries)
{ {
UnixFileSystemInfo[] entries = new UnixFileSystemInfo[dentries.Length]; UnixFileSystemInfo[] entries = new UnixFileSystemInfo[dentries.Length];
for (int i = 0; i != entries.Length; ++i) for (Int32 i = 0; i != entries.Length; ++i) {
entries [i] = UnixFileSystemInfo.GetFileSystemEntry ( entries [i] = UnixFileSystemInfo.GetFileSystemEntry (
UnixPath.Combine (FullPath, dentries[i].d_name)); UnixPath.Combine (this.FullPath, dentries[i].d_name));
}
return entries; return entries;
} }
public UnixFileSystemInfo[] GetFileSystemEntries (Regex regex) public UnixFileSystemInfo[] GetFileSystemEntries (Regex regex)
{ {
Native.Dirent[] dentries = GetEntries (regex); Native.Dirent[] dentries = this.GetEntries (regex);
return GetFileSystemEntries (dentries); return this.GetFileSystemEntries (dentries);
} }
public UnixFileSystemInfo[] GetFileSystemEntries (string regex) public UnixFileSystemInfo[] GetFileSystemEntries (String regex)
{ {
Regex re = new Regex (regex); Regex re = new Regex (regex);
return GetFileSystemEntries (re); return this.GetFileSystemEntries (re);
} }
public static string GetCurrentDirectory () public static String GetCurrentDirectory ()
{ {
StringBuilder buf = new StringBuilder (16); StringBuilder buf = new StringBuilder (16);
IntPtr r = IntPtr.Zero; IntPtr r = IntPtr.Zero;
do { do {
buf.Capacity *= 2; buf.Capacity *= 2;
r = Native.Syscall.getcwd (buf, (ulong) buf.Capacity); r = Native.Syscall.getcwd (buf, (UInt64) buf.Capacity);
} while (r == IntPtr.Zero && Native.Syscall.GetLastError() == Native.Errno.ERANGE); } while (r == IntPtr.Zero && Native.Syscall.GetLastError() == Native.Errno.ERANGE);
if (r == IntPtr.Zero) if (r == IntPtr.Zero) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return buf.ToString (); return buf.ToString ();
} }
public static void SetCurrentDirectory (string path) public static void SetCurrentDirectory (String path)
{ {
int r = Native.Syscall.chdir (path); Int32 r = Native.Syscall.chdir (path);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
} }

View File

@ -47,15 +47,17 @@ namespace Mono.Unix {
public sealed class UnixDriveInfo public sealed class UnixDriveInfo
{ {
private Native.Statvfs stat; private Native.Statvfs stat;
private string fstype, mount_point, block_device; private String fstype, mount_point, block_device;
public UnixDriveInfo (string mountPoint) public UnixDriveInfo (String mountPoint)
{ {
if (mountPoint == null) if (mountPoint == null) {
throw new ArgumentNullException ("mountPoint"); throw new ArgumentNullException ("mountPoint");
}
Native.Fstab fstab = Native.Syscall.getfsfile (mountPoint); Native.Fstab fstab = Native.Syscall.getfsfile (mountPoint);
if (fstab != null) { if (fstab != null) {
FromFstab (fstab); this.FromFstab (fstab);
} }
else { else {
this.mount_point = mountPoint; this.mount_point = mountPoint;
@ -71,72 +73,65 @@ namespace Mono.Unix {
this.block_device = fstab.fs_spec; this.block_device = fstab.fs_spec;
} }
public static UnixDriveInfo GetForSpecialFile (string specialFile) public static UnixDriveInfo GetForSpecialFile (String specialFile)
{ {
if (specialFile == null) if (specialFile == null) {
throw new ArgumentNullException ("specialFile"); throw new ArgumentNullException ("specialFile");
}
Native.Fstab f = Native.Syscall.getfsspec (specialFile); Native.Fstab f = Native.Syscall.getfsspec (specialFile);
if (f == null) if (f == null) {
throw new ArgumentException ("specialFile isn't valid: " + specialFile); throw new ArgumentException ("specialFile isn't valid: " + specialFile);
}
return new UnixDriveInfo (f); return new UnixDriveInfo (f);
} }
private UnixDriveInfo (Native.Fstab fstab) private UnixDriveInfo(Native.Fstab fstab) => this.FromFstab(fstab);
{
FromFstab (fstab); public Int64 AvailableFreeSpace {
get {
this.Refresh (); return Convert.ToInt64 (this.stat.f_bavail * this.stat.f_frsize);}
} }
public long AvailableFreeSpace { public String DriveFormat => this.fstype;
get {Refresh (); return Convert.ToInt64 (stat.f_bavail * stat.f_frsize);}
}
public string DriveFormat { public UnixDriveType DriveType => UnixDriveType.Unknown;
get {return fstype;}
}
public UnixDriveType DriveType {
get {return UnixDriveType.Unknown;}
}
// this throws no exceptions // this throws no exceptions
public bool IsReady { public Boolean IsReady {
get { get {
bool ready = Refresh (false); Boolean ready = this.Refresh (false);
if (mount_point == "/" || !ready) if (this.mount_point == "/" || !ready) {
return ready; return ready;
Native.Statvfs parent; }
int r = Native.Syscall.statvfs (RootDirectory.Parent.FullName,
out parent); Int32 r = Native.Syscall.statvfs(this.RootDirectory.Parent.FullName,
if (r != 0) out Native.Statvfs parent);
return false; return r != 0 ? false : parent.f_fsid != this.stat.f_fsid;
return parent.f_fsid != stat.f_fsid;
} }
} }
public string Name { public String Name => this.mount_point;
get {return mount_point;}
public UnixDirectoryInfo RootDirectory => new UnixDirectoryInfo(this.mount_point);
public Int64 TotalFreeSpace {
get {
this.Refresh (); return (Int64) (this.stat.f_bfree * this.stat.f_frsize);}
} }
public UnixDirectoryInfo RootDirectory { public Int64 TotalSize {
get {return new UnixDirectoryInfo (mount_point);} get {
} this.Refresh (); return (Int64) (this.stat.f_frsize * this.stat.f_blocks);}
public long TotalFreeSpace {
get {Refresh (); return (long) (stat.f_bfree * stat.f_frsize);}
}
public long TotalSize {
get {Refresh (); return (long) (stat.f_frsize * stat.f_blocks);}
} }
// also throws SecurityException if caller lacks perms // also throws SecurityException if caller lacks perms
public string VolumeLabel { public String VolumeLabel => this.block_device;
get {return block_device;}
// set {}
}
public long MaximumFilenameLength { public Int64 MaximumFilenameLength {
get {Refresh (); return Convert.ToInt64 (stat.f_namemax);} get {
this.Refresh (); return Convert.ToInt64 (this.stat.f_namemax);}
} }
public static UnixDriveInfo[] GetDrives () public static UnixDriveInfo[] GetDrives ()
@ -148,45 +143,44 @@ namespace Mono.Unix {
ArrayList entries = new ArrayList (); ArrayList entries = new ArrayList ();
lock (Native.Syscall.fstab_lock) { lock (Native.Syscall.fstab_lock) {
int r = Native.Syscall.setfsent (); Int32 r = Native.Syscall.setfsent ();
if (r != 1) if (r != 1) {
throw new IOException ("Error calling setfsent(3)", new UnixIOException ()); throw new IOException ("Error calling setfsent(3)", new UnixIOException ());
}
try { try {
Native.Fstab fs; Native.Fstab fs;
while ((fs = Native.Syscall.getfsent()) != null) { while ((fs = Native.Syscall.getfsent()) != null) {
// avoid virtual entries, such as "swap" // avoid virtual entries, such as "swap"
if (fs.fs_file != null && fs.fs_file.StartsWith ("/")) if (fs.fs_file != null && fs.fs_file.StartsWith ("/")) {
entries.Add (new UnixDriveInfo (fs)); _ = entries.Add(new UnixDriveInfo(fs));
}
} }
} }
finally { finally {
Native.Syscall.endfsent (); _ = Native.Syscall.endfsent();
} }
} }
return (UnixDriveInfo[]) entries.ToArray (typeof(UnixDriveInfo)); return (UnixDriveInfo[]) entries.ToArray (typeof(UnixDriveInfo));
} }
public override string ToString () public override String ToString() => this.VolumeLabel;
{
return VolumeLabel;
}
private void Refresh () private void Refresh() => this.Refresh(true);
{
Refresh (true);
}
private bool Refresh (bool throwException) private Boolean Refresh (Boolean throwException)
{ {
int r = Native.Syscall.statvfs (mount_point, out stat); Int32 r = Native.Syscall.statvfs (this.mount_point, out this.stat);
if (r == -1 && throwException) { if (r == -1 && throwException) {
Native.Errno e = Native.Syscall.GetLastError (); Native.Errno e = Native.Syscall.GetLastError ();
throw new InvalidOperationException ( throw new InvalidOperationException (
UnixMarshal.GetErrorDescription (e), UnixMarshal.GetErrorDescription (e),
new UnixIOException (e)); new UnixIOException (e));
} }
else if (r == -1) else if (r == -1) {
return false; return false;
}
return true; return true;
} }
} }

View File

@ -27,18 +27,18 @@
* OTHER DEALINGS IN THE SOFTWARE. * OTHER DEALINGS IN THE SOFTWARE.
*/ */
namespace Mono.Unix
{
using System; using System;
using System.Text; using System.Text;
namespace Mono.Unix
{
[Serializable] [Serializable]
public class UnixEncoding : Encoding public class UnixEncoding : Encoding
{ {
public static readonly Encoding Instance = new UnixEncoding (); public static readonly Encoding Instance = new UnixEncoding ();
public static readonly char EscapeByte = '\u0000'; public static readonly Char EscapeByte = '\u0000';
// Constructors. // Constructors.
public UnixEncoding () public UnixEncoding ()
@ -47,7 +47,7 @@ public class UnixEncoding : Encoding
// Internal version of "GetByteCount" which can handle a rolling // Internal version of "GetByteCount" which can handle a rolling
// state between multiple calls to this method. // state between multiple calls to this method.
private static int InternalGetByteCount (char[] chars, int index, int count, uint leftOver, bool flush) private static Int32 InternalGetByteCount (Char[] chars, Int32 index, Int32 count, UInt32 leftOver, Boolean flush)
{ {
// Validate the parameters. // Validate the parameters.
if (chars == null) { if (chars == null) {
@ -56,14 +56,14 @@ public class UnixEncoding : Encoding
if (index < 0 || index > chars.Length) { if (index < 0 || index > chars.Length) {
throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
} }
if (count < 0 || count > (chars.Length - index)) { if (count < 0 || count > chars.Length - index) {
throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
} }
// Determine the lengths of all characters. // Determine the lengths of all characters.
char ch; Char ch;
int length = 0; Int32 length = 0;
uint pair = leftOver; UInt32 pair = leftOver;
while (count > 0) { while (count > 0) {
ch = chars[index]; ch = chars[index];
if (pair == 0) { if (pair == 0) {
@ -77,7 +77,7 @@ public class UnixEncoding : Encoding
length += 2; length += 2;
} else if (ch >= '\uD800' && ch <= '\uDBFF') { } else if (ch >= '\uD800' && ch <= '\uDBFF') {
// This is the start of a surrogate pair. // This is the start of a surrogate pair.
pair = (uint)ch; pair = (UInt32)ch;
} else { } else {
length += 3; length += 3;
} }
@ -108,13 +108,10 @@ public class UnixEncoding : Encoding
} }
// Get the number of bytes needed to encode a character buffer. // Get the number of bytes needed to encode a character buffer.
public override int GetByteCount (char[] chars, int index, int count) public override Int32 GetByteCount(Char[] chars, Int32 index, Int32 count) => InternalGetByteCount(chars, index, count, 0, true);
{
return InternalGetByteCount (chars, index, count, 0, true);
}
// Convenience wrappers for "GetByteCount". // Convenience wrappers for "GetByteCount".
public override int GetByteCount (String s) public override Int32 GetByteCount (String s)
{ {
// Validate the parameters. // Validate the parameters.
if (s == null) { if (s == null) {
@ -122,11 +119,11 @@ public class UnixEncoding : Encoding
} }
// Determine the lengths of all characters. // Determine the lengths of all characters.
char ch; Char ch;
int index = 0; Int32 index = 0;
int count = s.Length; Int32 count = s.Length;
int length = 0; Int32 length = 0;
uint pair; UInt32 pair;
while (count > 0) { while (count > 0) {
ch = s[index++]; ch = s[index++];
if (ch == EscapeByte && count > 1) { if (ch == EscapeByte && count > 1) {
@ -139,8 +136,8 @@ public class UnixEncoding : Encoding
length += 2; length += 2;
} else if (ch >= '\uD800' && ch <= '\uDBFF' && count > 1) { } else if (ch >= '\uD800' && ch <= '\uDBFF' && count > 1) {
// This may be the start of a surrogate pair. // This may be the start of a surrogate pair.
pair = (uint)(s[index]); pair = (UInt32)s[index];
if (pair >= (uint)0xDC00 && pair <= (uint)0xDFFF) { if (pair >= (UInt32)0xDC00 && pair <= (UInt32)0xDFFF) {
length += 4; length += 4;
++index; ++index;
--count; --count;
@ -159,10 +156,10 @@ public class UnixEncoding : Encoding
// Internal version of "GetBytes" which can handle a rolling // Internal version of "GetBytes" which can handle a rolling
// state between multiple calls to this method. // state between multiple calls to this method.
private static int InternalGetBytes (char[] chars, int charIndex, private static Int32 InternalGetBytes (Char[] chars, Int32 charIndex,
int charCount, byte[] bytes, Int32 charCount, Byte[] bytes,
int byteIndex, ref uint leftOver, Int32 byteIndex, ref UInt32 leftOver,
bool flush) Boolean flush)
{ {
// Validate the parameters. // Validate the parameters.
if (chars == null) { if (chars == null) {
@ -174,7 +171,7 @@ public class UnixEncoding : Encoding
if (charIndex < 0 || charIndex > chars.Length) { if (charIndex < 0 || charIndex > chars.Length) {
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
} }
if (charCount < 0 || charCount > (chars.Length - charIndex)) { if (charCount < 0 || charCount > chars.Length - charIndex) {
throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
} }
if (byteIndex < 0 || byteIndex > bytes.Length) { if (byteIndex < 0 || byteIndex > bytes.Length) {
@ -182,11 +179,11 @@ public class UnixEncoding : Encoding
} }
// Convert the characters into bytes. // Convert the characters into bytes.
char ch; Char ch;
int length = bytes.Length; Int32 length = bytes.Length;
uint pair; UInt32 pair;
uint left = leftOver; UInt32 left = leftOver;
int posn = byteIndex; Int32 posn = byteIndex;
while (charCount > 0) { while (charCount > 0) {
// Fetch the next UTF-16 character pair value. // Fetch the next UTF-16 character pair value.
ch = chars[charIndex++]; ch = chars[charIndex++];
@ -194,25 +191,25 @@ public class UnixEncoding : Encoding
if (left == 0) { if (left == 0) {
if (ch >= '\uD800' && ch <= '\uDBFF') { if (ch >= '\uD800' && ch <= '\uDBFF') {
// This is the start of a surrogate pair. // This is the start of a surrogate pair.
left = (uint)ch; left = (UInt32)ch;
continue; continue;
} else if (ch == EscapeByte) { } else if (ch == EscapeByte) {
if (posn >= length) { if (posn >= length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
if (--charCount >= 0) { if (--charCount >= 0) {
bytes[posn++] = (byte) chars [charIndex++]; bytes[posn++] = (Byte) chars [charIndex++];
} }
continue; continue;
} else { } else {
// This is a regular character. // This is a regular character.
pair = (uint)ch; pair = (UInt32)ch;
} }
} else if (ch >= '\uDC00' && ch <= '\uDFFF') { } else if (ch >= '\uDC00' && ch <= '\uDFFF') {
// We have a surrogate pair. // We have a surrogate pair.
pair = ((left - (uint)0xD800) << 10) + pair = ((left - (UInt32)0xD800) << 10) +
(((uint)ch) - (uint)0xDC00) + ((UInt32)ch - (UInt32)0xDC00) +
(uint)0x10000; (UInt32)0x10000;
left = 0; left = 0;
} else { } else {
// We have a surrogate start followed by a // We have a surrogate start followed by a
@ -220,49 +217,49 @@ public class UnixEncoding : Encoding
// invalid, but we have to do something. // invalid, but we have to do something.
// We write out the surrogate start and then // We write out the surrogate start and then
// re-visit the current character again. // re-visit the current character again.
pair = (uint)left; pair = (UInt32)left;
left = 0; left = 0;
--charIndex; --charIndex;
++charCount; ++charCount;
} }
// Encode the character pair value. // Encode the character pair value.
if (pair < (uint)0x0080) { if (pair < (UInt32)0x0080) {
if (posn >= length) { if (posn >= length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)pair; bytes[posn++] = (Byte)pair;
} else if (pair < (uint)0x0800) { } else if (pair < (UInt32)0x0800) {
if ((posn + 2) > length) { if (posn + 2 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xC0 | (pair >> 6)); bytes[posn++] = (Byte)(0xC0 | (pair >> 6));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} else if (pair < (uint)0x10000) { } else if (pair < (UInt32)0x10000) {
if ((posn + 3) > length) { if (posn + 3 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xE0 | (pair >> 12)); bytes[posn++] = (Byte)(0xE0 | (pair >> 12));
bytes[posn++] = (byte)(0x80 | ((pair >> 6) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 6) & 0x3F));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} else { } else {
if ((posn + 4) > length) { if (posn + 4 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xF0 | (pair >> 18)); bytes[posn++] = (Byte)(0xF0 | (pair >> 18));
bytes[posn++] = (byte)(0x80 | ((pair >> 12) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 12) & 0x3F));
bytes[posn++] = (byte)(0x80 | ((pair >> 6) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 6) & 0x3F));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} }
} }
if (flush && left != 0) { if (flush && left != 0) {
// Flush the left-over surrogate pair start. // Flush the left-over surrogate pair start.
if ((posn + 3) > length) { if (posn + 3 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xE0 | (left >> 12)); bytes[posn++] = (Byte)(0xE0 | (left >> 12));
bytes[posn++] = (byte)(0x80 | ((left >> 6) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((left >> 6) & 0x3F));
bytes[posn++] = (byte)(0x80 | (left & 0x3F)); bytes[posn++] = (Byte)(0x80 | (left & 0x3F));
left = 0; left = 0;
} }
leftOver = left; leftOver = left;
@ -272,16 +269,16 @@ public class UnixEncoding : Encoding
} }
// Get the bytes that result from encoding a character buffer. // Get the bytes that result from encoding a character buffer.
public override int GetBytes (char[] chars, int charIndex, int charCount, public override Int32 GetBytes (Char[] chars, Int32 charIndex, Int32 charCount,
byte[] bytes, int byteIndex) Byte[] bytes, Int32 byteIndex)
{ {
uint leftOver = 0; UInt32 leftOver = 0;
return InternalGetBytes (chars, charIndex, charCount, bytes, byteIndex, ref leftOver, true); return InternalGetBytes (chars, charIndex, charCount, bytes, byteIndex, ref leftOver, true);
} }
// Convenience wrappers for "GetBytes". // Convenience wrappers for "GetBytes".
public override int GetBytes (String s, int charIndex, int charCount, public override Int32 GetBytes (String s, Int32 charIndex, Int32 charCount,
byte[] bytes, int byteIndex) Byte[] bytes, Int32 byteIndex)
{ {
// Validate the parameters. // Validate the parameters.
if (s == null) { if (s == null) {
@ -293,7 +290,7 @@ public class UnixEncoding : Encoding
if (charIndex < 0 || charIndex > s.Length) { if (charIndex < 0 || charIndex > s.Length) {
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_StringIndex")); throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_StringIndex"));
} }
if (charCount < 0 || charCount > (s.Length - charIndex)) { if (charCount < 0 || charCount > s.Length - charIndex) {
throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_StringRange")); throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_StringRange"));
} }
if (byteIndex < 0 || byteIndex > bytes.Length) { if (byteIndex < 0 || byteIndex > bytes.Length) {
@ -301,42 +298,44 @@ public class UnixEncoding : Encoding
} }
unsafe { unsafe {
fixed (char* p = s) { fixed (Char* p = s) {
fixed (byte* b = bytes) { fixed (Byte* b = bytes) {
return GetBytes (p + charIndex, charCount, b + byteIndex, bytes.Length - byteIndex); return this.GetBytes (p + charIndex, charCount, b + byteIndex, bytes.Length - byteIndex);
} }
} }
} }
} }
public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) public unsafe override Int32 GetBytes(Char* chars, Int32 charCount, Byte* bytes, Int32 byteCount)
{ {
if (bytes == null || chars == null) if (bytes == null || chars == null) {
throw new ArgumentNullException (bytes == null ? "bytes" : "chars"); throw new ArgumentNullException (bytes == null ? "bytes" : "chars");
}
if (charCount < 0 || byteCount < 0) if (charCount < 0 || byteCount < 0) {
throw new ArgumentOutOfRangeException (charCount < 0 ? "charCount" : "byteCount"); throw new ArgumentOutOfRangeException (charCount < 0 ? "charCount" : "byteCount");
}
// Convert the characters into bytes. // Convert the characters into bytes.
char ch; Char ch;
int length = byteCount; Int32 length = byteCount;
uint pair; UInt32 pair;
int posn = 0; Int32 posn = 0;
int charIndex = 0; Int32 charIndex = 0;
while (charCount > 0) { while (charCount > 0) {
// Fetch the next UTF-16 character pair value. // Fetch the next UTF-16 character pair value.
ch = chars [charIndex++]; ch = chars [charIndex++];
if (ch >= '\uD800' && ch <= '\uDBFF' && charCount > 1) { if (ch >= '\uD800' && ch <= '\uDBFF' && charCount > 1) {
// This may be the start of a surrogate pair. // This may be the start of a surrogate pair.
pair = (uint)(chars[charIndex]); pair = (UInt32)chars[charIndex];
if (pair >= (uint)0xDC00 && pair <= (uint)0xDFFF) { if (pair >= (UInt32)0xDC00 && pair <= (UInt32)0xDFFF) {
pair = (pair - (uint)0xDC00) + pair = pair - (UInt32)0xDC00 +
((((uint)ch) - (uint)0xD800) << 10) + (((UInt32)ch - (UInt32)0xD800) << 10) +
(uint)0x10000; (UInt32)0x10000;
++charIndex; ++charIndex;
--charCount; --charCount;
} else { } else {
pair = (uint)ch; pair = (UInt32)ch;
} }
} else if (ch == EscapeByte && charCount > 1) { } else if (ch == EscapeByte && charCount > 1) {
if (posn >= length) { if (posn >= length) {
@ -344,41 +343,41 @@ public class UnixEncoding : Encoding
} }
charCount -= 2; charCount -= 2;
if (charCount >= 0) { if (charCount >= 0) {
bytes[posn++] = (byte)chars [charIndex++]; bytes[posn++] = (Byte)chars [charIndex++];
} }
continue; continue;
} else { } else {
pair = (uint)ch; pair = (UInt32)ch;
} }
--charCount; --charCount;
// Encode the character pair value. // Encode the character pair value.
if (pair < (uint)0x0080) { if (pair < (UInt32)0x0080) {
if (posn >= length) { if (posn >= length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)pair; bytes[posn++] = (Byte)pair;
} else if (pair < (uint)0x0800) { } else if (pair < (UInt32)0x0800) {
if ((posn + 2) > length) { if (posn + 2 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xC0 | (pair >> 6)); bytes[posn++] = (Byte)(0xC0 | (pair >> 6));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} else if (pair < (uint)0x10000) { } else if (pair < (UInt32)0x10000) {
if ((posn + 3) > length) { if (posn + 3 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xE0 | (pair >> 12)); bytes[posn++] = (Byte)(0xE0 | (pair >> 12));
bytes[posn++] = (byte)(0x80 | ((pair >> 6) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 6) & 0x3F));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} else { } else {
if ((posn + 4) > length) { if (posn + 4 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes"); throw new ArgumentException (_("Arg_InsufficientSpace"), "bytes");
} }
bytes[posn++] = (byte)(0xF0 | (pair >> 18)); bytes[posn++] = (Byte)(0xF0 | (pair >> 18));
bytes[posn++] = (byte)(0x80 | ((pair >> 12) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 12) & 0x3F));
bytes[posn++] = (byte)(0x80 | ((pair >> 6) & 0x3F)); bytes[posn++] = (Byte)(0x80 | ((pair >> 6) & 0x3F));
bytes[posn++] = (byte)(0x80 | (pair & 0x3F)); bytes[posn++] = (Byte)(0x80 | (pair & 0x3F));
} }
} }
@ -388,10 +387,10 @@ public class UnixEncoding : Encoding
// Internal version of "GetCharCount" which can handle a rolling // Internal version of "GetCharCount" which can handle a rolling
// state between multiple calls to this method. // state between multiple calls to this method.
private static int InternalGetCharCount (byte[] bytes, int index, int count, private static Int32 InternalGetCharCount (Byte[] bytes, Int32 index, Int32 count,
uint leftOverBits, UInt32 leftOverBits,
uint leftOverCount, UInt32 leftOverCount,
bool throwOnInvalid, bool flush) Boolean throwOnInvalid, Boolean flush)
{ {
// Validate the parameters. // Validate the parameters.
if (bytes == null) { if (bytes == null) {
@ -400,50 +399,50 @@ public class UnixEncoding : Encoding
if (index < 0 || index > bytes.Length) { if (index < 0 || index > bytes.Length) {
throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
} }
if (count < 0 || count > (bytes.Length - index)) { if (count < 0 || count > bytes.Length - index) {
throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
} }
// Determine the number of characters that we have. // Determine the number of characters that we have.
int next_raw = 0; Int32 next_raw = 0;
uint ch; UInt32 ch;
int length = 0; Int32 length = 0;
uint leftBits = leftOverBits; UInt32 leftBits = leftOverBits;
uint leftSoFar = (leftOverCount & (uint)0x0F); UInt32 leftSoFar = leftOverCount & (UInt32)0x0F;
uint leftSize = ((leftOverCount >> 4) & (uint)0x0F); UInt32 leftSize = (leftOverCount >> 4) & (UInt32)0x0F;
while (count > 0) { while (count > 0) {
ch = (uint)(bytes [index++]); ch = (UInt32)bytes [index++];
++next_raw; ++next_raw;
--count; --count;
if (leftSize == 0) { if (leftSize == 0) {
// Process a UTF-8 start character. // Process a UTF-8 start character.
if (ch < (uint)0x0080) { if (ch < (UInt32)0x0080) {
// Single-byte UTF-8 character. // Single-byte UTF-8 character.
++length; ++length;
next_raw = 0; next_raw = 0;
} else if ((ch & (uint)0xE0) == (uint)0xC0) { } else if ((ch & (UInt32)0xE0) == (UInt32)0xC0) {
// Double-byte UTF-8 character. // Double-byte UTF-8 character.
leftBits = (ch & (uint)0x1F); leftBits = ch & (UInt32)0x1F;
leftSoFar = 1; leftSoFar = 1;
leftSize = 2; leftSize = 2;
} else if ((ch & (uint)0xF0) == (uint)0xE0) { } else if ((ch & (UInt32)0xF0) == (UInt32)0xE0) {
// Three-byte UTF-8 character. // Three-byte UTF-8 character.
leftBits = (ch & (uint)0x0F); leftBits = ch & (UInt32)0x0F;
leftSoFar = 1; leftSoFar = 1;
leftSize = 3; leftSize = 3;
} else if ((ch & (uint)0xF8) == (uint)0xF0) { } else if ((ch & (UInt32)0xF8) == (UInt32)0xF0) {
// Four-byte UTF-8 character. // Four-byte UTF-8 character.
leftBits = (ch & (uint)0x07); leftBits = ch & (UInt32)0x07;
leftSoFar = 1; leftSoFar = 1;
leftSize = 4; leftSize = 4;
} else if ((ch & (uint)0xFC) == (uint)0xF8) { } else if ((ch & (UInt32)0xFC) == (UInt32)0xF8) {
// Five-byte UTF-8 character. // Five-byte UTF-8 character.
leftBits = (ch & (uint)0x03); leftBits = ch & (UInt32)0x03;
leftSoFar = 1; leftSoFar = 1;
leftSize = 5; leftSize = 5;
} else if ((ch & (uint)0xFE) == (uint)0xFC) { } else if ((ch & (UInt32)0xFE) == (UInt32)0xFC) {
// Six-byte UTF-8 character. // Six-byte UTF-8 character.
leftBits = (ch & (uint)0x03); leftBits = ch & (UInt32)0x03;
leftSoFar = 1; leftSoFar = 1;
leftSize = 6; leftSize = 6;
} else { } else {
@ -456,28 +455,28 @@ public class UnixEncoding : Encoding
} }
} else { } else {
// Process an extra byte in a multi-byte sequence. // Process an extra byte in a multi-byte sequence.
if ((ch & (uint)0xC0) == (uint)0x80) { if ((ch & (UInt32)0xC0) == (UInt32)0x80) {
leftBits = ((leftBits << 6) | (ch & (uint)0x3F)); leftBits = (leftBits << 6) | (ch & (UInt32)0x3F);
if (++leftSoFar >= leftSize) { if (++leftSoFar >= leftSize) {
// We have a complete character now. // We have a complete character now.
if (leftBits < (uint)0x10000) { if (leftBits < (UInt32)0x10000) {
// is it an overlong ? // is it an overlong ?
bool overlong = false; Boolean overlong = false;
switch (leftSize) { switch (leftSize) {
case 2: case 2:
overlong = (leftBits <= 0x7F); overlong = leftBits <= 0x7F;
break; break;
case 3: case 3:
overlong = (leftBits <= 0x07FF); overlong = leftBits <= 0x07FF;
break; break;
case 4: case 4:
overlong = (leftBits <= 0xFFFF); overlong = leftBits <= 0xFFFF;
break; break;
case 5: case 5:
overlong = (leftBits <= 0x1FFFFF); overlong = leftBits <= 0x1FFFFF;
break; break;
case 6: case 6:
overlong = (leftBits <= 0x03FFFFFF); overlong = leftBits <= 0x03FFFFFF;
break; break;
} }
if (overlong) { if (overlong) {
@ -485,9 +484,10 @@ public class UnixEncoding : Encoding
// throw new ArgumentException (_("Overlong"), leftBits.ToString ()); // throw new ArgumentException (_("Overlong"), leftBits.ToString ());
length += next_raw*2; length += next_raw*2;
} }
else else {
++length; ++length;
} else if (leftBits < (uint)0x110000) { }
} else if (leftBits < (UInt32)0x110000) {
length += 2; length += 2;
} else if (throwOnInvalid) { } else if (throwOnInvalid) {
// ??? // ???
@ -503,7 +503,7 @@ public class UnixEncoding : Encoding
// throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes"); // throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes");
} }
// don't escape the current byte, process it normally // don't escape the current byte, process it normally
if (ch < (uint)0x0080) { if (ch < (UInt32)0x0080) {
--index; --index;
++count; ++count;
--next_raw; --next_raw;
@ -526,17 +526,14 @@ public class UnixEncoding : Encoding
} }
// Get the number of characters needed to decode a byte buffer. // Get the number of characters needed to decode a byte buffer.
public override int GetCharCount (byte[] bytes, int index, int count) public override Int32 GetCharCount(Byte[] bytes, Int32 index, Int32 count) => InternalGetCharCount(bytes, index, count, 0, 0, true, true);
{
return InternalGetCharCount (bytes, index, count, 0, 0, true, true);
}
// Get the characters that result from decoding a byte buffer. // Get the characters that result from decoding a byte buffer.
private static int InternalGetChars (byte[] bytes, int byteIndex, private static Int32 InternalGetChars (Byte[] bytes, Int32 byteIndex,
int byteCount, char[] chars, Int32 byteCount, Char[] chars,
int charIndex, ref uint leftOverBits, Int32 charIndex, ref UInt32 leftOverBits,
ref uint leftOverCount, ref UInt32 leftOverCount,
bool throwOnInvalid, bool flush) Boolean throwOnInvalid, Boolean flush)
{ {
// Validate the parameters. // Validate the parameters.
if (bytes == null) { if (bytes == null) {
@ -548,62 +545,63 @@ public class UnixEncoding : Encoding
if (byteIndex < 0 || byteIndex > bytes.Length) { if (byteIndex < 0 || byteIndex > bytes.Length) {
throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
} }
if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) { if (byteCount < 0 || byteCount > bytes.Length - byteIndex) {
throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
} }
if (charIndex < 0 || charIndex > chars.Length) { if (charIndex < 0 || charIndex > chars.Length) {
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array")); throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
} }
if (charIndex == chars.Length) if (charIndex == chars.Length) {
return 0; return 0;
}
// Convert the bytes into the output buffer. // Convert the bytes into the output buffer.
byte[] raw = new byte[6]; Byte[] raw = new Byte[6];
int next_raw = 0; Int32 next_raw = 0;
uint ch; UInt32 ch;
int length = chars.Length; Int32 length = chars.Length;
int posn = charIndex; Int32 posn = charIndex;
uint leftBits = leftOverBits; UInt32 leftBits = leftOverBits;
uint leftSoFar = (leftOverCount & (uint)0x0F); UInt32 leftSoFar = leftOverCount & (UInt32)0x0F;
uint leftSize = ((leftOverCount >> 4) & (uint)0x0F); UInt32 leftSize = (leftOverCount >> 4) & (UInt32)0x0F;
while (byteCount > 0) { while (byteCount > 0) {
// Fetch the next character from the byte buffer. // Fetch the next character from the byte buffer.
ch = (uint)(bytes[byteIndex++]); ch = (UInt32)bytes[byteIndex++];
raw [next_raw++] = (byte) ch; raw [next_raw++] = (Byte) ch;
--byteCount; --byteCount;
if (leftSize == 0) { if (leftSize == 0) {
// Process a UTF-8 start character. // Process a UTF-8 start character.
if (ch < (uint)0x0080) { if (ch < (UInt32)0x0080) {
// Single-byte UTF-8 character. // Single-byte UTF-8 character.
if (posn >= length) { if (posn >= length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "chars"); throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
} }
next_raw = 0; next_raw = 0;
chars[posn++] = (char)ch; chars[posn++] = (Char)ch;
} else if ((ch & (uint)0xE0) == (uint)0xC0) { } else if ((ch & (UInt32)0xE0) == (UInt32)0xC0) {
// Double-byte UTF-8 character. // Double-byte UTF-8 character.
leftBits = (ch & (uint)0x1F); leftBits = ch & (UInt32)0x1F;
leftSoFar = 1; leftSoFar = 1;
leftSize = 2; leftSize = 2;
} else if ((ch & (uint)0xF0) == (uint)0xE0) { } else if ((ch & (UInt32)0xF0) == (UInt32)0xE0) {
// Three-byte UTF-8 character. // Three-byte UTF-8 character.
leftBits = (ch & (uint)0x0F); leftBits = ch & (UInt32)0x0F;
leftSoFar = 1; leftSoFar = 1;
leftSize = 3; leftSize = 3;
} else if ((ch & (uint)0xF8) == (uint)0xF0) { } else if ((ch & (UInt32)0xF8) == (UInt32)0xF0) {
// Four-byte UTF-8 character. // Four-byte UTF-8 character.
leftBits = (ch & (uint)0x07); leftBits = ch & (UInt32)0x07;
leftSoFar = 1; leftSoFar = 1;
leftSize = 4; leftSize = 4;
} else if ((ch & (uint)0xFC) == (uint)0xF8) { } else if ((ch & (UInt32)0xFC) == (UInt32)0xF8) {
// Five-byte UTF-8 character. // Five-byte UTF-8 character.
leftBits = (ch & (uint)0x03); leftBits = ch & (UInt32)0x03;
leftSoFar = 1; leftSoFar = 1;
leftSize = 5; leftSize = 5;
} else if ((ch & (uint)0xFE) == (uint)0xFC) { } else if ((ch & (UInt32)0xFE) == (UInt32)0xFC) {
// Six-byte UTF-8 character. // Six-byte UTF-8 character.
leftBits = (ch & (uint)0x03); leftBits = ch & (UInt32)0x03;
leftSoFar = 1; leftSoFar = 1;
leftSize = 6; leftSize = 6;
} else { } else {
@ -613,32 +611,32 @@ public class UnixEncoding : Encoding
} }
next_raw = 0; next_raw = 0;
chars[posn++] = EscapeByte; chars[posn++] = EscapeByte;
chars[posn++] = (char) ch; chars[posn++] = (Char) ch;
} }
} else { } else {
// Process an extra byte in a multi-byte sequence. // Process an extra byte in a multi-byte sequence.
if ((ch & (uint)0xC0) == (uint)0x80) { if ((ch & (UInt32)0xC0) == (UInt32)0x80) {
leftBits = ((leftBits << 6) | (ch & (uint)0x3F)); leftBits = (leftBits << 6) | (ch & (UInt32)0x3F);
if (++leftSoFar >= leftSize) { if (++leftSoFar >= leftSize) {
// We have a complete character now. // We have a complete character now.
if (leftBits < (uint)0x10000) { if (leftBits < (UInt32)0x10000) {
// is it an overlong ? // is it an overlong ?
bool overlong = false; Boolean overlong = false;
switch (leftSize) { switch (leftSize) {
case 2: case 2:
overlong = (leftBits <= 0x7F); overlong = leftBits <= 0x7F;
break; break;
case 3: case 3:
overlong = (leftBits <= 0x07FF); overlong = leftBits <= 0x07FF;
break; break;
case 4: case 4:
overlong = (leftBits <= 0xFFFF); overlong = leftBits <= 0xFFFF;
break; break;
case 5: case 5:
overlong = (leftBits <= 0x1FFFFF); overlong = leftBits <= 0x1FFFFF;
break; break;
case 6: case 6:
overlong = (leftBits <= 0x03FFFFFF); overlong = leftBits <= 0x03FFFFFF;
break; break;
} }
if (overlong) { if (overlong) {
@ -651,18 +649,18 @@ public class UnixEncoding : Encoding
throw new ArgumentException throw new ArgumentException
(_("Arg_InsufficientSpace"), "chars"); (_("Arg_InsufficientSpace"), "chars");
} }
chars[posn++] = (char)leftBits; chars[posn++] = (Char)leftBits;
} }
} else if (leftBits < (uint)0x110000) { } else if (leftBits < (UInt32)0x110000) {
if ((posn + 2) > length) { if (posn + 2 > length) {
throw new ArgumentException throw new ArgumentException
(_("Arg_InsufficientSpace"), "chars"); (_("Arg_InsufficientSpace"), "chars");
} }
leftBits -= (uint)0x10000; leftBits -= (UInt32)0x10000;
chars[posn++] = (char)((leftBits >> 10) + chars[posn++] = (Char)((leftBits >> 10) +
(uint)0xD800); (UInt32)0xD800);
chars[posn++] = chars[posn++] =
(char)((leftBits & (uint)0x3FF) + (uint)0xDC00); (Char)((leftBits & (UInt32)0x3FF) + (UInt32)0xDC00);
} else if (throwOnInvalid) { } else if (throwOnInvalid) {
// ??? // ???
// throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes"); // throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes");
@ -677,7 +675,7 @@ public class UnixEncoding : Encoding
// throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes"); // throw new ArgumentException (_("Arg_InvalidUTF8"), "bytes");
} }
// don't escape the current byte, process it normally // don't escape the current byte, process it normally
if (ch < (uint)0x0080) { if (ch < (UInt32)0x0080) {
--byteIndex; --byteIndex;
++byteCount; ++byteCount;
--next_raw; --next_raw;
@ -695,38 +693,39 @@ public class UnixEncoding : Encoding
CopyRaw (raw, ref next_raw, chars, ref posn, length); CopyRaw (raw, ref next_raw, chars, ref posn, length);
} }
leftOverBits = leftBits; leftOverBits = leftBits;
leftOverCount = (leftSoFar | (leftSize << 4)); leftOverCount = leftSoFar | (leftSize << 4);
// Return the final length to the caller. // Return the final length to the caller.
return posn - charIndex; return posn - charIndex;
} }
private static void CopyRaw (byte[] raw, ref int next_raw, char[] chars, ref int posn, int length) private static void CopyRaw (Byte[] raw, ref Int32 next_raw, Char[] chars, ref Int32 posn, Int32 length)
{ {
if (posn+(next_raw*2) > length) if (posn+next_raw*2 > length) {
throw new ArgumentException (_("Arg_InsufficientSpace"), "chars"); throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
}
for (int i = 0; i < next_raw; ++i) { for (Int32 i = 0; i < next_raw; ++i) {
chars[posn++] = EscapeByte; chars[posn++] = EscapeByte;
chars[posn++] = (char) raw [i]; chars[posn++] = (Char) raw [i];
} }
next_raw = 0; next_raw = 0;
} }
// Get the characters that result from decoding a byte buffer. // Get the characters that result from decoding a byte buffer.
public override int GetChars (byte[] bytes, int byteIndex, int byteCount, public override Int32 GetChars (Byte[] bytes, Int32 byteIndex, Int32 byteCount,
char[] chars, int charIndex) Char[] chars, Int32 charIndex)
{ {
uint leftOverBits = 0; UInt32 leftOverBits = 0;
uint leftOverCount = 0; UInt32 leftOverCount = 0;
return InternalGetChars (bytes, byteIndex, byteCount, chars, return InternalGetChars (bytes, byteIndex, byteCount, chars,
charIndex, ref leftOverBits, ref leftOverCount, true, true); charIndex, ref leftOverBits, ref leftOverCount, true, true);
} }
// Get the maximum number of bytes needed to encode a // Get the maximum number of bytes needed to encode a
// specified number of characters. // specified number of characters.
public override int GetMaxByteCount (int charCount) public override Int32 GetMaxByteCount (Int32 charCount)
{ {
if (charCount < 0) { if (charCount < 0) {
throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative")); throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative"));
@ -736,7 +735,7 @@ public class UnixEncoding : Encoding
// Get the maximum number of characters needed to decode a // Get the maximum number of characters needed to decode a
// specified number of bytes. // specified number of bytes.
public override int GetMaxCharCount (int byteCount) public override Int32 GetMaxCharCount (Int32 byteCount)
{ {
if (byteCount < 0) { if (byteCount < 0) {
throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_NonNegative")); throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_NonNegative"));
@ -745,49 +744,29 @@ public class UnixEncoding : Encoding
} }
// Get a Unix-specific decoder that is attached to this instance. // Get a Unix-specific decoder that is attached to this instance.
public override Decoder GetDecoder () public override Decoder GetDecoder() => new UnixDecoder();
{
return new UnixDecoder ();
}
// Get a Unix-specific encoder that is attached to this instance. // Get a Unix-specific encoder that is attached to this instance.
public override Encoder GetEncoder () public override Encoder GetEncoder() => new UnixEncoder();
{
return new UnixEncoder ();
}
// Get the Unix preamble. // Get the Unix preamble.
public override byte[] GetPreamble () public override Byte[] GetPreamble() => new Byte[0];
{
return new byte [0];
}
// Determine if this object is equal to another. // Determine if this object is equal to another.
public override bool Equals (Object value) public override Boolean Equals(Object value) => value is UnixEncoding;
{
UnixEncoding enc = (value as UnixEncoding);
if (enc != null) {
return true;
}
else {
return false;
}
}
// Get the hash code for this object. // Get the hash code for this object.
public override int GetHashCode () public override Int32 GetHashCode() => base.GetHashCode();
public override Byte[] GetBytes (String s)
{ {
return base.GetHashCode (); if (s == null) {
throw new ArgumentNullException ("s");
} }
public override byte [] GetBytes (String s) Int32 length = this.GetByteCount (s);
{ Byte[] bytes = new Byte[length];
if (s == null) this.GetBytes(s, 0, s.Length, bytes, 0);
throw new ArgumentNullException ("s");
int length = GetByteCount (s);
byte [] bytes = new byte [length];
GetBytes (s, 0, s.Length, bytes, 0);
return bytes; return bytes;
} }
@ -795,28 +774,22 @@ public class UnixEncoding : Encoding
[Serializable] [Serializable]
private class UnixDecoder : Decoder private class UnixDecoder : Decoder
{ {
private uint leftOverBits; private UInt32 leftOverBits;
private uint leftOverCount; private UInt32 leftOverCount;
// Constructor. // Constructor.
public UnixDecoder () public UnixDecoder ()
{ {
leftOverBits = 0; this.leftOverBits = 0;
leftOverCount = 0; this.leftOverCount = 0;
} }
// Override inherited methods. // Override inherited methods.
public override int GetCharCount (byte[] bytes, int index, int count) public override Int32 GetCharCount(Byte[] bytes, Int32 index, Int32 count) => InternalGetCharCount(bytes, index, count,
{ this.leftOverBits, this.leftOverCount, true, false);
return InternalGetCharCount (bytes, index, count, public override Int32 GetChars(Byte[] bytes, Int32 byteIndex,
leftOverBits, leftOverCount, true, false); Int32 byteCount, Char[] chars, Int32 charIndex) => InternalGetChars(bytes, byteIndex, byteCount,
} chars, charIndex, ref this.leftOverBits, ref this.leftOverCount, true, false);
public override int GetChars (byte[] bytes, int byteIndex,
int byteCount, char[] chars, int charIndex)
{
return InternalGetChars (bytes, byteIndex, byteCount,
chars, charIndex, ref leftOverBits, ref leftOverCount, true, false);
}
} }
@ -824,33 +797,24 @@ public class UnixEncoding : Encoding
[Serializable] [Serializable]
private class UnixEncoder : Encoder private class UnixEncoder : Encoder
{ {
private uint leftOver; private UInt32 leftOver;
// Constructor. // Constructor.
public UnixEncoder () public UnixEncoder() => this.leftOver = 0;
{
leftOver = 0;
}
// Override inherited methods. // Override inherited methods.
public override int GetByteCount (char[] chars, int index, public override Int32 GetByteCount(Char[] chars, Int32 index,
int count, bool flush) Int32 count, Boolean flush) => InternalGetByteCount(chars, index, count, this.leftOver, flush);
public override Int32 GetBytes (Char[] chars, Int32 charIndex,
Int32 charCount, Byte[] bytes, Int32 byteCount, Boolean flush)
{ {
return InternalGetByteCount (chars, index, count, leftOver, flush); Int32 result;
} result = InternalGetBytes (chars, charIndex, charCount, bytes, byteCount, ref this.leftOver, flush);
public override int GetBytes (char[] chars, int charIndex,
int charCount, byte[] bytes, int byteCount, bool flush)
{
int result;
result = InternalGetBytes (chars, charIndex, charCount, bytes, byteCount, ref leftOver, flush);
return result; return result;
} }
} }
private static string _ (string arg) private static String _(String arg) => arg;
{
return arg;
} }
} }
}

View File

@ -37,30 +37,27 @@ namespace Mono.Unix
[Serializable] [Serializable]
public class UnixEndPoint : EndPoint public class UnixEndPoint : EndPoint
{ {
string filename; String filename;
public UnixEndPoint (string filename) public UnixEndPoint (String filename)
{ {
if (filename == null) if (filename == null) {
throw new ArgumentNullException ("filename"); throw new ArgumentNullException ("filename");
}
if (filename == "") if (filename == "") {
throw new ArgumentException ("Cannot be empty.", "filename"); throw new ArgumentException ("Cannot be empty.", "filename");
}
this.filename = filename; this.filename = filename;
} }
public string Filename { public String Filename {
get { get => this.filename;
return(filename); set => this.filename = value;
}
set {
filename=value;
}
} }
public override AddressFamily AddressFamily { public override AddressFamily AddressFamily => AddressFamily.Unix;
get { return AddressFamily.Unix; }
}
public override EndPoint Create (SocketAddress socketAddress) public override EndPoint Create (SocketAddress socketAddress)
{ {
@ -78,13 +75,14 @@ namespace Mono.Unix
if (socketAddress.Size == 2) { if (socketAddress.Size == 2) {
// Empty filename. // Empty filename.
// Probably from RemoteEndPoint which on linux does not return the file name. // Probably from RemoteEndPoint which on linux does not return the file name.
UnixEndPoint uep = new UnixEndPoint ("a"); UnixEndPoint uep = new UnixEndPoint("a") {
uep.filename = ""; filename = ""
};
return uep; return uep;
} }
int size = socketAddress.Size - 2; Int32 size = socketAddress.Size - 2;
byte [] bytes = new byte [size]; Byte[] bytes = new Byte[size];
for (int i = 0; i < bytes.Length; i++) { for (Int32 i = 0; i < bytes.Length; i++) {
bytes [i] = socketAddress [i + 2]; bytes [i] = socketAddress [i + 2];
// There may be junk after the null terminator, so ignore it all. // There may be junk after the null terminator, so ignore it all.
if (bytes [i] == 0) { if (bytes [i] == 0) {
@ -93,17 +91,18 @@ namespace Mono.Unix
} }
} }
string name = Encoding.Default.GetString (bytes, 0, size); String name = Encoding.Default.GetString (bytes, 0, size);
return new UnixEndPoint (name); return new UnixEndPoint (name);
} }
public override SocketAddress Serialize () public override SocketAddress Serialize ()
{ {
byte [] bytes = Encoding.Default.GetBytes (filename); Byte[] bytes = Encoding.Default.GetBytes (this.filename);
SocketAddress sa = new SocketAddress (AddressFamily, 2 + bytes.Length + 1); SocketAddress sa = new SocketAddress (this.AddressFamily, 2 + bytes.Length + 1);
// sa [0] -> family low byte, sa [1] -> family high byte // sa [0] -> family low byte, sa [1] -> family high byte
for (int i = 0; i < bytes.Length; i++) for (Int32 i = 0; i < bytes.Length; i++) {
sa [2 + i] = bytes [i]; sa [2 + i] = bytes [i];
}
//NULL suffix for non-abstract path //NULL suffix for non-abstract path
sa[2 + bytes.Length] = 0; sa[2 + bytes.Length] = 0;
@ -111,22 +110,18 @@ namespace Mono.Unix
return sa; return sa;
} }
public override string ToString() { public override String ToString() => this.filename;
return(filename);
}
public override int GetHashCode () public override Int32 GetHashCode() => this.filename.GetHashCode();
{
return filename.GetHashCode ();
}
public override bool Equals (object o) public override Boolean Equals (Object o)
{ {
UnixEndPoint other = o as UnixEndPoint; UnixEndPoint other = o as UnixEndPoint;
if (other == null) if (other == null) {
return false; return false;
}
return (other.filename == filename); return other.filename == this.filename;
} }
} }
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;
using Mono.Unix; using Mono.Unix;
@ -37,200 +38,192 @@ namespace Mono.Unix {
{ {
private UnixEnvironment () {} private UnixEnvironment () {}
public static string CurrentDirectory { public static String CurrentDirectory {
get { get => UnixDirectoryInfo.GetCurrentDirectory();
return UnixDirectoryInfo.GetCurrentDirectory (); set => UnixDirectoryInfo.SetCurrentDirectory(value);
}
set {
UnixDirectoryInfo.SetCurrentDirectory (value);
}
} }
public static string MachineName { public static String MachineName {
get { get {
Native.Utsname buf; if(Native.Syscall.uname(out Native.Utsname buf) != 0) {
if (Native.Syscall.uname (out buf) != 0) throw UnixMarshal.CreateExceptionForLastError();
throw UnixMarshal.CreateExceptionForLastError (); }
return buf.nodename; return buf.nodename;
} }
set { set {
int r = Native.Syscall.sethostname (value); Int32 r = Native.Syscall.sethostname (value);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
} }
public static string UserName { public static String UserName => UnixUserInfo.GetRealUser().UserName;
get {return UnixUserInfo.GetRealUser ().UserName;}
}
public static UnixGroupInfo RealGroup { public static UnixGroupInfo RealGroup => new UnixGroupInfo(RealGroupId);
get {return new UnixGroupInfo (RealGroupId);}
// set can't be done as setgid(2) modifies effective gid as well
}
public static long RealGroupId { public static Int64 RealGroupId => Native.Syscall.getgid();
get {return Native.Syscall.getgid ();}
// set can't be done as setgid(2) modifies effective gid as well
}
public static UnixUserInfo RealUser { public static UnixUserInfo RealUser => new UnixUserInfo(RealUserId);
get {return new UnixUserInfo (RealUserId);}
// set can't be done as setuid(2) modifies effective uid as well
}
public static long RealUserId { public static Int64 RealUserId => Native.Syscall.getuid();
get {return Native.Syscall.getuid ();}
// set can't be done as setuid(2) modifies effective uid as well
}
public static UnixGroupInfo EffectiveGroup { public static UnixGroupInfo EffectiveGroup {
get {return new UnixGroupInfo (EffectiveGroupId);} get => new UnixGroupInfo(EffectiveGroupId);
set {EffectiveGroupId = value.GroupId;} set => EffectiveGroupId = value.GroupId;
} }
public static long EffectiveGroupId { public static Int64 EffectiveGroupId {
get {return Native.Syscall.getegid ();} get => Native.Syscall.getegid();
set {Native.Syscall.setegid (Convert.ToUInt32 (value));} set => _ = Native.Syscall.setegid(Convert.ToUInt32(value));
} }
public static UnixUserInfo EffectiveUser { public static UnixUserInfo EffectiveUser {
get {return new UnixUserInfo (EffectiveUserId);} get => new UnixUserInfo(EffectiveUserId);
set {EffectiveUserId = value.UserId;} set => EffectiveUserId = value.UserId;
} }
public static long EffectiveUserId { public static Int64 EffectiveUserId {
get {return Native.Syscall.geteuid ();} get => Native.Syscall.geteuid();
set {Native.Syscall.seteuid (Convert.ToUInt32 (value));} set => _ = Native.Syscall.seteuid(Convert.ToUInt32(value));
} }
public static string Login { public static String Login => UnixUserInfo.GetRealUser().UserName;
get {return UnixUserInfo.GetRealUser ().UserName;}
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public static long GetConfigurationValue (Native.SysconfName name) public static Int64 GetConfigurationValue (Native.SysconfName name)
{ {
long r = Native.Syscall.sysconf (name); Int64 r = Native.Syscall.sysconf (name);
if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0) if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return r; return r;
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public static string GetConfigurationString (Native.ConfstrName name) public static String GetConfigurationString (Native.ConfstrName name)
{ {
ulong len = Native.Syscall.confstr (name, null, 0); UInt64 len = Native.Syscall.confstr (name, null, 0);
if (len == unchecked ((ulong) (-1))) if (len == unchecked ((UInt64) (-1))) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
if (len == 0) }
if (len == 0) {
return ""; return "";
StringBuilder buf = new StringBuilder ((int) len+1); }
StringBuilder buf = new StringBuilder ((Int32) len+1);
len = Native.Syscall.confstr (name, buf, len); len = Native.Syscall.confstr (name, buf, len);
if (len == unchecked ((ulong) (-1))) if (len == unchecked ((UInt64) (-1))) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return buf.ToString (); return buf.ToString ();
} }
public static void SetNiceValue (int inc) public static void SetNiceValue (Int32 inc)
{ {
int r = Native.Syscall.nice (inc); Int32 r = Native.Syscall.nice (inc);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static int CreateSession () public static Int32 CreateSession ()
{ {
int s = Native.Syscall.setsid (); Int32 s = Native.Syscall.setsid ();
UnixMarshal.ThrowExceptionForLastErrorIf (s); UnixMarshal.ThrowExceptionForLastErrorIf (s);
return s; return s;
} }
public static void SetProcessGroup () public static void SetProcessGroup ()
{ {
int r = Native.Syscall.setpgrp (); Int32 r = Native.Syscall.setpgrp ();
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static int GetProcessGroup () public static Int32 GetProcessGroup() => Native.Syscall.getpgrp();
{
return Native.Syscall.getpgrp ();
}
public static UnixGroupInfo[] GetSupplementaryGroups () public static UnixGroupInfo[] GetSupplementaryGroups ()
{ {
uint[] ids = _GetSupplementaryGroupIds (); UInt32[] ids = _GetSupplementaryGroupIds ();
UnixGroupInfo[] groups = new UnixGroupInfo [ids.Length]; UnixGroupInfo[] groups = new UnixGroupInfo [ids.Length];
for (int i = 0; i < groups.Length; ++i) for (Int32 i = 0; i < groups.Length; ++i) {
groups [i] = new UnixGroupInfo (ids [i]); groups [i] = new UnixGroupInfo (ids [i]);
}
return groups; return groups;
} }
private static uint[] _GetSupplementaryGroupIds () [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static UInt32[] _GetSupplementaryGroupIds ()
{ {
int ngroups = Native.Syscall.getgroups (0, new uint[]{}); Int32 ngroups = Native.Syscall.getgroups (0, new UInt32[]{});
if (ngroups == -1) if (ngroups == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
uint[] groups = new uint[ngroups]; }
int r = Native.Syscall.getgroups (groups);
UInt32[] groups = new UInt32[ngroups];
Int32 r = Native.Syscall.getgroups (groups);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return groups; return groups;
} }
public static void SetSupplementaryGroups (UnixGroupInfo[] groups) public static void SetSupplementaryGroups (UnixGroupInfo[] groups)
{ {
uint[] list = new uint [groups.Length]; UInt32[] list = new UInt32[groups.Length];
for (int i = 0; i < list.Length; ++i) { for (Int32 i = 0; i < list.Length; ++i) {
list [i] = Convert.ToUInt32 (groups [i].GroupId); list [i] = Convert.ToUInt32 (groups [i].GroupId);
} }
int r = Native.Syscall.setgroups (list); Int32 r = Native.Syscall.setgroups (list);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static long[] GetSupplementaryGroupIds () public static Int64[] GetSupplementaryGroupIds ()
{ {
uint[] _groups = _GetSupplementaryGroupIds (); UInt32[] _groups = _GetSupplementaryGroupIds ();
long[] groups = new long [_groups.Length]; Int64[] groups = new Int64[_groups.Length];
for (int i = 0; i < groups.Length; ++i) for (Int32 i = 0; i < groups.Length; ++i) {
groups [i] = _groups [i]; groups [i] = _groups [i];
}
return groups; return groups;
} }
public static void SetSupplementaryGroupIds (long[] list) public static void SetSupplementaryGroupIds (Int64[] list)
{ {
uint[] _list = new uint [list.Length]; UInt32[] _list = new UInt32[list.Length];
for (int i = 0; i < _list.Length; ++i) for (Int32 i = 0; i < _list.Length; ++i) {
_list [i] = Convert.ToUInt32 (list [i]); _list [i] = Convert.ToUInt32 (list [i]);
int r = Native.Syscall.setgroups (_list); }
Int32 r = Native.Syscall.setgroups (_list);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public static int GetParentProcessId () public static Int32 GetParentProcessId() => Native.Syscall.getppid();
{
return Native.Syscall.getppid ();
}
public static UnixProcess GetParentProcess () public static UnixProcess GetParentProcess() => new UnixProcess(GetParentProcessId());
{
return new UnixProcess (GetParentProcessId ());
}
public static string[] GetUserShells () public static String[] GetUserShells ()
{ {
ArrayList shells = new ArrayList (); ArrayList shells = new ArrayList ();
lock (Native.Syscall.usershell_lock) { lock (Native.Syscall.usershell_lock) {
try { try {
if (Native.Syscall.setusershell () != 0) if (Native.Syscall.setusershell () != 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
string shell; }
while ((shell = Native.Syscall.getusershell ()) != null)
shells.Add (shell); String shell;
while ((shell = Native.Syscall.getusershell ()) != null) {
_ = shells.Add(shell);
}
} }
finally { finally {
Native.Syscall.endusershell (); _ = Native.Syscall.endusershell();
} }
} }
return (string[]) shells.ToArray (typeof(string)); return (String[]) shells.ToArray (typeof(String));
} }
} }
} }

View File

@ -35,31 +35,25 @@ namespace Mono.Unix {
public sealed class UnixFileInfo : UnixFileSystemInfo public sealed class UnixFileInfo : UnixFileSystemInfo
{ {
public UnixFileInfo (string path) public UnixFileInfo (String path)
: base (path) : base (path)
{ {
} }
internal UnixFileInfo (string path, Native.Stat stat) internal UnixFileInfo (String path, Native.Stat stat)
: base (path, stat) : base (path, stat)
{ {
} }
public override string Name { public override String Name => UnixPath.GetFileName(this.FullPath);
get {return UnixPath.GetFileName (FullPath);}
}
public string DirectoryName { public String DirectoryName => UnixPath.GetDirectoryName(this.FullPath);
get {return UnixPath.GetDirectoryName (FullPath);}
}
public UnixDirectoryInfo Directory { public UnixDirectoryInfo Directory => new UnixDirectoryInfo(this.DirectoryName);
get {return new UnixDirectoryInfo (DirectoryName);}
}
public override void Delete () public override void Delete ()
{ {
int r = Native.Syscall.unlink (FullPath); Int32 r = Native.Syscall.unlink (this.FullPath);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
base.Refresh (); base.Refresh ();
} }
@ -69,78 +63,79 @@ namespace Mono.Unix {
Native.FilePermissions mode = // 0644 Native.FilePermissions mode = // 0644
Native.FilePermissions.S_IRUSR | Native.FilePermissions.S_IWUSR | Native.FilePermissions.S_IRUSR | Native.FilePermissions.S_IWUSR |
Native.FilePermissions.S_IRGRP | Native.FilePermissions.S_IROTH; Native.FilePermissions.S_IRGRP | Native.FilePermissions.S_IROTH;
return Create (mode); return this.Create (mode);
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public UnixStream Create (Native.FilePermissions mode) public UnixStream Create (Native.FilePermissions mode)
{ {
int fd = Native.Syscall.creat (FullPath, mode); Int32 fd = Native.Syscall.creat (this.FullPath, mode);
if (fd < 0) if (fd < 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
base.Refresh (); base.Refresh ();
return new UnixStream (fd); return new UnixStream (fd);
} }
public UnixStream Create (FileAccessPermissions mode) public UnixStream Create(FileAccessPermissions mode) => this.Create((Native.FilePermissions)mode);
{
return Create ((Native.FilePermissions) mode);
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public UnixStream Open (Native.OpenFlags flags) public UnixStream Open (Native.OpenFlags flags)
{ {
if ((flags & Native.OpenFlags.O_CREAT) != 0) if ((flags & Native.OpenFlags.O_CREAT) != 0) {
throw new ArgumentException ( throw new ArgumentException (
"Cannot specify OpenFlags.O_CREAT without providing " + "Cannot specify OpenFlags.O_CREAT without providing " +
"FilePermissions. Use the Open(OpenFlags, FilePermissions) " + "FilePermissions. Use the Open(OpenFlags, FilePermissions) " +
"method instead"); "method instead");
int fd = Native.Syscall.open (FullPath, flags); }
if (fd < 0)
Int32 fd = Native.Syscall.open (this.FullPath, flags);
if (fd < 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return new UnixStream (fd); return new UnixStream (fd);
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public UnixStream Open (Native.OpenFlags flags, Native.FilePermissions mode) public UnixStream Open (Native.OpenFlags flags, Native.FilePermissions mode)
{ {
int fd = Native.Syscall.open (FullPath, flags, mode); Int32 fd = Native.Syscall.open (this.FullPath, flags, mode);
if (fd < 0) if (fd < 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return new UnixStream (fd); return new UnixStream (fd);
} }
public UnixStream Open (FileMode mode) public UnixStream Open (FileMode mode)
{ {
Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, FileAccess.ReadWrite); Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, FileAccess.ReadWrite);
return Open (flags); return this.Open (flags);
} }
public UnixStream Open (FileMode mode, FileAccess access) public UnixStream Open (FileMode mode, FileAccess access)
{ {
Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, access); Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, access);
return Open (flags); return this.Open (flags);
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public UnixStream Open (FileMode mode, FileAccess access, Native.FilePermissions perms) public UnixStream Open (FileMode mode, FileAccess access, Native.FilePermissions perms)
{ {
Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, access); Native.OpenFlags flags = Native.NativeConvert.ToOpenFlags (mode, access);
int fd = Native.Syscall.open (FullPath, flags, perms); Int32 fd = Native.Syscall.open (this.FullPath, flags, perms);
if (fd < 0) if (fd < 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return new UnixStream (fd); return new UnixStream (fd);
} }
public UnixStream OpenRead () public UnixStream OpenRead() => this.Open(FileMode.Open, FileAccess.Read);
{
return Open (FileMode.Open, FileAccess.Read);
}
public UnixStream OpenWrite () public UnixStream OpenWrite() => this.Open(FileMode.OpenOrCreate, FileAccess.Write);
{
return Open (FileMode.OpenOrCreate, FileAccess.Write);
}
} }
} }

View File

@ -36,9 +36,9 @@ namespace Mono.Unix {
public abstract class UnixFileSystemInfo public abstract class UnixFileSystemInfo
{ {
private Native.Stat stat; private Native.Stat stat;
private string fullPath; private String fullPath;
private string originalPath; private String originalPath;
private bool valid = false; private Boolean valid = false;
internal const FileSpecialAttributes AllSpecialAttributes = internal const FileSpecialAttributes AllSpecialAttributes =
FileSpecialAttributes.SetUserId | FileSpecialAttributes.SetGroupId | FileSpecialAttributes.SetUserId | FileSpecialAttributes.SetGroupId |
@ -48,12 +48,12 @@ namespace Mono.Unix {
FileTypes.RegularFile | FileTypes.Fifo | FileTypes.SymbolicLink | FileTypes.RegularFile | FileTypes.Fifo | FileTypes.SymbolicLink |
FileTypes.Socket; FileTypes.Socket;
protected UnixFileSystemInfo (string path) protected UnixFileSystemInfo (String path)
{ {
UnixPath.CheckPath (path); UnixPath.CheckPath (path);
this.originalPath = path; this.originalPath = path;
this.fullPath = UnixPath.GetFullPath (path); this.fullPath = UnixPath.GetFullPath (path);
Refresh (true); this.Refresh (true);
} }
internal UnixFileSystemInfo (String path, Native.Stat stat) internal UnixFileSystemInfo (String path, Native.Stat stat)
@ -64,333 +64,349 @@ namespace Mono.Unix {
this.valid = true; this.valid = true;
} }
protected string FullPath { protected String FullPath {
get {return fullPath;} get => this.fullPath;
set { set {
if (fullPath != value) { if(this.fullPath != value) {
UnixPath.CheckPath (value); UnixPath.CheckPath(value);
valid = false; this.valid = false;
fullPath = value; this.fullPath = value;
} }
} }
} }
protected string OriginalPath { protected String OriginalPath {
get {return originalPath;} get => this.originalPath;
set {originalPath = value;} set => this.originalPath = value;
} }
private void AssertValid () private void AssertValid ()
{ {
Refresh (false); this.Refresh (false);
if (!valid) if (!this.valid) {
throw new InvalidOperationException ("Path doesn't exist!"); throw new InvalidOperationException ("Path doesn't exist!");
} }
public virtual string FullName {
get {return FullPath;}
} }
public abstract string Name {get;} public virtual String FullName => this.FullPath;
public bool Exists { public abstract String Name {get;}
public Boolean Exists {
get { get {
Refresh (true); this.Refresh (true);
return valid; return this.valid;
} }
} }
public long Device { public Int64 Device {
get {AssertValid (); return Convert.ToInt64 (stat.st_dev);} get {
this.AssertValid (); return Convert.ToInt64 (this.stat.st_dev);}
} }
public long Inode { public Int64 Inode {
get {AssertValid (); return Convert.ToInt64 (stat.st_ino);} get {
this.AssertValid (); return Convert.ToInt64 (this.stat.st_ino);}
} }
[CLSCompliant (false)] //[CLSCompliant (false)]
public Native.FilePermissions Protection { public Native.FilePermissions Protection {
get {AssertValid (); return (Native.FilePermissions) stat.st_mode;} get {
this.AssertValid (); return (Native.FilePermissions)this.stat.st_mode;}
set { set {
int r = Native.Syscall.chmod (FullPath, value); Int32 r = Native.Syscall.chmod (this.FullPath, value);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
} }
public FileTypes FileType { public FileTypes FileType {
get { get {
AssertValid (); this.AssertValid ();
return (FileTypes) (stat.st_mode & Native.FilePermissions.S_IFMT); return (FileTypes) (this.stat.st_mode & Native.FilePermissions.S_IFMT);
} }
// no set as chmod(2) won't accept changing the file type. // no set as chmod(2) won't accept changing the file type.
} }
public FileAccessPermissions FileAccessPermissions { public FileAccessPermissions FileAccessPermissions {
get { get {
AssertValid (); this.AssertValid ();
int perms = (int) stat.st_mode; Int32 perms = (Int32)this.stat.st_mode;
return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions); return (FileAccessPermissions) (perms & (Int32) FileAccessPermissions.AllPermissions);
} }
set { set {
AssertValid (); this.AssertValid ();
int perms = (int) stat.st_mode; Int32 perms = (Int32)this.stat.st_mode;
perms &= (int) ~FileAccessPermissions.AllPermissions; perms &= (Int32) ~FileAccessPermissions.AllPermissions;
perms |= (int) value; perms |= (Int32) value;
Protection = (Native.FilePermissions) perms; this.Protection = (Native.FilePermissions) perms;
} }
} }
public FileSpecialAttributes FileSpecialAttributes { public FileSpecialAttributes FileSpecialAttributes {
get { get {
AssertValid (); this.AssertValid ();
int attrs = (int) stat.st_mode; Int32 attrs = (Int32)this.stat.st_mode;
return (FileSpecialAttributes) (attrs & (int) AllSpecialAttributes); return (FileSpecialAttributes) (attrs & (Int32) AllSpecialAttributes);
} }
set { set {
AssertValid (); this.AssertValid ();
int perms = (int) stat.st_mode; Int32 perms = (Int32)this.stat.st_mode;
perms &= (int) ~AllSpecialAttributes; perms &= (Int32) ~AllSpecialAttributes;
perms |= (int) value; perms |= (Int32) value;
Protection = (Native.FilePermissions) perms; this.Protection = (Native.FilePermissions) perms;
} }
} }
public long LinkCount { public Int64 LinkCount {
get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);} get {
this.AssertValid (); return Convert.ToInt64 (this.stat.st_nlink);}
} }
public UnixUserInfo OwnerUser { public UnixUserInfo OwnerUser {
get {AssertValid (); return new UnixUserInfo (stat.st_uid);} get {
this.AssertValid (); return new UnixUserInfo (this.stat.st_uid);}
} }
public long OwnerUserId { public Int64 OwnerUserId {
get {AssertValid (); return stat.st_uid;} get {
this.AssertValid (); return this.stat.st_uid;}
} }
public UnixGroupInfo OwnerGroup { public UnixGroupInfo OwnerGroup {
get {AssertValid (); return new UnixGroupInfo (stat.st_gid);} get {
this.AssertValid (); return new UnixGroupInfo (this.stat.st_gid);}
} }
public long OwnerGroupId { public Int64 OwnerGroupId {
get {AssertValid (); return stat.st_gid;} get {
this.AssertValid (); return this.stat.st_gid;}
} }
public long DeviceType { public Int64 DeviceType {
get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);} get {
this.AssertValid (); return Convert.ToInt64 (this.stat.st_rdev);}
} }
public long Length { public Int64 Length {
get {AssertValid (); return (long) stat.st_size;} get {
this.AssertValid (); return (Int64)this.stat.st_size;}
} }
public long BlockSize { public Int64 BlockSize {
get {AssertValid (); return (long) stat.st_blksize;} get {
this.AssertValid (); return (Int64)this.stat.st_blksize;}
} }
public long BlocksAllocated { public Int64 BlocksAllocated {
get {AssertValid (); return (long) stat.st_blocks;} get {
this.AssertValid (); return (Int64)this.stat.st_blocks;}
} }
public DateTime LastAccessTime { public DateTime LastAccessTime {
get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime, stat.st_atime_nsec);} get {
this.AssertValid (); return Native.NativeConvert.ToDateTime (this.stat.st_atime, this.stat.st_atime_nsec);}
} }
public DateTime LastAccessTimeUtc { public DateTime LastAccessTimeUtc => this.LastAccessTime.ToUniversalTime();
get {return LastAccessTime.ToUniversalTime ();}
}
public DateTime LastWriteTime { public DateTime LastWriteTime {
get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime, stat.st_mtime_nsec);} get {
this.AssertValid (); return Native.NativeConvert.ToDateTime (this.stat.st_mtime, this.stat.st_mtime_nsec);}
} }
public DateTime LastWriteTimeUtc { public DateTime LastWriteTimeUtc => this.LastWriteTime.ToUniversalTime();
get {return LastWriteTime.ToUniversalTime ();}
}
public DateTime LastStatusChangeTime { public DateTime LastStatusChangeTime {
get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime, stat.st_ctime_nsec);} get {
this.AssertValid (); return Native.NativeConvert.ToDateTime (this.stat.st_ctime, this.stat.st_ctime_nsec);}
} }
public DateTime LastStatusChangeTimeUtc { public DateTime LastStatusChangeTimeUtc => this.LastStatusChangeTime.ToUniversalTime();
get {return LastStatusChangeTime.ToUniversalTime ();}
public Boolean IsDirectory {
get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFDIR);}
} }
public bool IsDirectory { public Boolean IsCharacterDevice {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFCHR);}
} }
public bool IsCharacterDevice { public Boolean IsBlockDevice {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFCHR);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFBLK);}
} }
public bool IsBlockDevice { public Boolean IsRegularFile {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFBLK);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFREG);}
} }
public bool IsRegularFile { public Boolean IsFifo {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFREG);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFIFO);}
} }
public bool IsFifo { public Boolean IsSymbolicLink {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFIFO);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFLNK);}
} }
public bool IsSymbolicLink { public Boolean IsSocket {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFLNK);} get {
this.AssertValid (); return IsFileType (this.stat.st_mode, Native.FilePermissions.S_IFSOCK);}
} }
public bool IsSocket { public Boolean IsSetUser {
get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFSOCK);} get {
this.AssertValid (); return IsSet (this.stat.st_mode, Native.FilePermissions.S_ISUID);}
} }
public bool IsSetUser { public Boolean IsSetGroup {
get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISUID);} get {
this.AssertValid (); return IsSet (this.stat.st_mode, Native.FilePermissions.S_ISGID);}
} }
public bool IsSetGroup { public Boolean IsSticky {
get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISGID);} get {
this.AssertValid (); return IsSet (this.stat.st_mode, Native.FilePermissions.S_ISVTX);}
} }
public bool IsSticky { internal static Boolean IsFileType(Native.FilePermissions mode, Native.FilePermissions type) => (mode & Native.FilePermissions.S_IFMT) == type;
get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISVTX);}
}
internal static bool IsFileType (Native.FilePermissions mode, Native.FilePermissions type) internal static Boolean IsSet(Native.FilePermissions mode, Native.FilePermissions type) => (mode & type) == type;
//[CLSCompliant (false)]
public Boolean CanAccess (Native.AccessModes mode)
{ {
return (mode & Native.FilePermissions.S_IFMT) == type; Int32 r = Native.Syscall.access (this.FullPath, mode);
}
internal static bool IsSet (Native.FilePermissions mode, Native.FilePermissions type)
{
return (mode & type) == type;
}
[CLSCompliant (false)]
public bool CanAccess (Native.AccessModes mode)
{
int r = Native.Syscall.access (FullPath, mode);
return r == 0; return r == 0;
} }
public UnixFileSystemInfo CreateLink (string path) public UnixFileSystemInfo CreateLink (String path)
{ {
int r = Native.Syscall.link (FullName, path); Int32 r = Native.Syscall.link (this.FullName, path);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return GetFileSystemEntry (path); return GetFileSystemEntry (path);
} }
public UnixSymbolicLinkInfo CreateSymbolicLink (string path) public UnixSymbolicLinkInfo CreateSymbolicLink (String path)
{ {
int r = Native.Syscall.symlink (FullName, path); Int32 r = Native.Syscall.symlink (this.FullName, path);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return new UnixSymbolicLinkInfo (path); return new UnixSymbolicLinkInfo (path);
} }
public abstract void Delete (); public abstract void Delete ();
[CLSCompliant (false)] //[CLSCompliant (false)]
public long GetConfigurationValue (Native.PathconfName name) public Int64 GetConfigurationValue (Native.PathconfName name)
{ {
long r = Native.Syscall.pathconf (FullPath, name); Int64 r = Native.Syscall.pathconf (this.FullPath, name);
if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0) if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return r; return r;
} }
public void Refresh () public void Refresh() => this.Refresh(true);
{
Refresh (true);
}
internal void Refresh (bool force) internal void Refresh (Boolean force)
{ {
if (valid && !force) if (this.valid && !force) {
return; return;
valid = GetFileStatus (FullPath, out this.stat);
} }
protected virtual bool GetFileStatus (string path, out Native.Stat stat) this.valid = this.GetFileStatus (this.FullPath, out this.stat);
{
return Native.Syscall.stat (path, out stat) == 0;
} }
public void SetLength (long length) protected virtual Boolean GetFileStatus(String path, out Native.Stat stat) => Native.Syscall.stat(path, out stat) == 0;
public void SetLength (Int64 length)
{ {
int r; Int32 r;
do { do {
r = Native.Syscall.truncate (FullPath, length); r = Native.Syscall.truncate (this.FullPath, length);
} while (UnixMarshal.ShouldRetrySyscall (r)); } while (UnixMarshal.ShouldRetrySyscall (r));
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public virtual void SetOwner (long owner, long group) public virtual void SetOwner (Int64 owner, Int64 group)
{ {
uint _owner = Convert.ToUInt32 (owner); UInt32 _owner = Convert.ToUInt32 (owner);
uint _group = Convert.ToUInt32 (group); UInt32 _group = Convert.ToUInt32 (group);
int r = Native.Syscall.chown (FullPath, _owner, _group); Int32 r = Native.Syscall.chown (this.FullPath, _owner, _group);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public void SetOwner (string owner) public void SetOwner (String owner)
{ {
Native.Passwd pw = Native.Syscall.getpwnam (owner); Native.Passwd pw = Native.Syscall.getpwnam (owner);
if (pw == null) if (pw == null) {
throw new ArgumentException (Locale.GetText ("invalid username"), "owner"); throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
uint uid = pw.pw_uid;
uint gid = pw.pw_gid;
SetOwner ((long) uid, (long) gid);
} }
public void SetOwner (string owner, string group) UInt32 uid = pw.pw_uid;
{ UInt32 gid = pw.pw_gid;
long uid = -1; this.SetOwner ((Int64) uid, (Int64) gid);
if (owner != null) }
uid = new UnixUserInfo (owner).UserId;
long gid = -1;
if (group != null)
gid = new UnixGroupInfo (group).GroupId;
SetOwner (uid, gid); public void SetOwner (String owner, String group)
{
Int64 uid = -1;
if (owner != null) {
uid = new UnixUserInfo (owner).UserId;
}
Int64 gid = -1;
if (group != null) {
gid = new UnixGroupInfo (group).GroupId;
}
this.SetOwner (uid, gid);
} }
public void SetOwner (UnixUserInfo owner) public void SetOwner (UnixUserInfo owner)
{ {
long uid, gid; Int64 uid, gid;
uid = gid = -1; uid = gid = -1;
if (owner != null) { if (owner != null) {
uid = owner.UserId; uid = owner.UserId;
gid = owner.GroupId; gid = owner.GroupId;
} }
SetOwner (uid, gid); this.SetOwner (uid, gid);
} }
public void SetOwner (UnixUserInfo owner, UnixGroupInfo group) public void SetOwner (UnixUserInfo owner, UnixGroupInfo group)
{ {
long uid, gid; Int64 uid, gid;
uid = gid = -1; uid = gid = -1;
if (owner != null) if (owner != null) {
uid = owner.UserId; uid = owner.UserId;
if (group != null)
gid = owner.GroupId;
SetOwner (uid, gid);
} }
public override string ToString () if (group != null) {
{ gid = owner.GroupId;
return FullPath;
} }
this.SetOwner (uid, gid);
}
public override String ToString() => this.FullPath;
public Native.Stat ToStat () public Native.Stat ToStat ()
{ {
AssertValid (); this.AssertValid ();
return stat; return this.stat;
} }
public static UnixFileSystemInfo GetFileSystemEntry (string path) public static UnixFileSystemInfo GetFileSystemEntry (String path)
{ {
UnixFileSystemInfo info; if(TryGetFileSystemEntry(path, out UnixFileSystemInfo info)) {
if (TryGetFileSystemEntry (path, out info))
return info; return info;
}
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
@ -400,10 +416,9 @@ namespace Mono.Unix {
throw new DirectoryNotFoundException ("UnixMarshal.ThrowExceptionForLastError didn't throw?!"); throw new DirectoryNotFoundException ("UnixMarshal.ThrowExceptionForLastError didn't throw?!");
} }
public static bool TryGetFileSystemEntry (string path, out UnixFileSystemInfo entry) public static Boolean TryGetFileSystemEntry (String path, out UnixFileSystemInfo entry)
{ {
Native.Stat stat; Int32 r = Native.Syscall.lstat(path, out Native.Stat stat);
int r = Native.Syscall.lstat (path, out stat);
if (r == -1) { if (r == -1) {
if (Native.Stdlib.GetLastError() == Native.Errno.ENOENT) { if (Native.Stdlib.GetLastError() == Native.Errno.ENOENT) {
entry = new UnixFileInfo (path); entry = new UnixFileInfo (path);
@ -413,13 +428,11 @@ namespace Mono.Unix {
return false; return false;
} }
if (IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR)) entry = IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR)
entry = new UnixDirectoryInfo (path, stat); ? new UnixDirectoryInfo (path, stat)
else if (IsFileType (stat.st_mode, Native.FilePermissions.S_IFLNK)) : IsFileType(stat.st_mode, Native.FilePermissions.S_IFLNK)
entry = new UnixSymbolicLinkInfo (path, stat); ? new UnixSymbolicLinkInfo(path, stat)
else : (UnixFileSystemInfo)new UnixFileInfo(path, stat);
entry = new UnixFileInfo (path, stat);
return true; return true;
} }
} }

View File

@ -35,61 +35,47 @@ namespace Mono.Unix {
public sealed class UnixGroupInfo public sealed class UnixGroupInfo
{ {
private Native.Group group; private readonly Native.Group group;
public UnixGroupInfo (string group) public UnixGroupInfo (String group)
{ {
this.group = new Native.Group (); this.group = new Native.Group ();
Native.Group gr; Int32 r = Native.Syscall.getgrnam_r(group, this.group, out Native.Group gr);
int r = Native.Syscall.getgrnam_r (group, this.group, out gr); if (r != 0 || gr == null) {
if (r != 0 || gr == null)
throw new ArgumentException (Locale.GetText ("invalid group name"), "group"); throw new ArgumentException (Locale.GetText ("invalid group name"), "group");
} }
}
public UnixGroupInfo (long group) public UnixGroupInfo (Int64 group)
{ {
this.group = new Native.Group (); this.group = new Native.Group ();
Native.Group gr; Int32 r = Native.Syscall.getgrgid_r(Convert.ToUInt32(group), this.group, out Native.Group gr);
int r = Native.Syscall.getgrgid_r (Convert.ToUInt32 (group), this.group, out gr); if (r != 0 || gr == null) {
if (r != 0 || gr == null)
throw new ArgumentException (Locale.GetText ("invalid group id"), "group"); throw new ArgumentException (Locale.GetText ("invalid group id"), "group");
} }
public UnixGroupInfo (Native.Group group)
{
this.group = CopyGroup (group);
} }
private static Native.Group CopyGroup (Native.Group group) public UnixGroupInfo(Native.Group group) => this.group = CopyGroup(group);
{
Native.Group g = new Native.Group ();
g.gr_gid = group.gr_gid; private static Native.Group CopyGroup(Native.Group group) => new Native.Group {
g.gr_mem = group.gr_mem; gr_gid = group.gr_gid,
g.gr_name = group.gr_name; gr_mem = group.gr_mem,
g.gr_passwd = group.gr_passwd; gr_name = group.gr_name,
gr_passwd = group.gr_passwd
};
return g; public String GroupName => this.group.gr_name;
}
public string GroupName { public String Password => this.group.gr_passwd;
get {return group.gr_name;}
}
public string Password { public Int64 GroupId => this.group.gr_gid;
get {return group.gr_passwd;}
}
public long GroupId {
get {return group.gr_gid;}
}
public UnixUserInfo[] GetMembers () public UnixUserInfo[] GetMembers ()
{ {
ArrayList members = new ArrayList (group.gr_mem.Length); ArrayList members = new ArrayList (this.group.gr_mem.Length);
for (int i = 0; i < group.gr_mem.Length; ++i) { for (Int32 i = 0; i < this.group.gr_mem.Length; ++i) {
try { try {
members.Add (new UnixUserInfo (group.gr_mem [i])); _ = members.Add(new UnixUserInfo(this.group.gr_mem[i]));
} catch (ArgumentException) { } catch (ArgumentException) {
// ignore invalid users // ignore invalid users
} }
@ -97,48 +83,36 @@ namespace Mono.Unix {
return (UnixUserInfo[]) members.ToArray (typeof (UnixUserInfo)); return (UnixUserInfo[]) members.ToArray (typeof (UnixUserInfo));
} }
public string[] GetMemberNames () public String[] GetMemberNames() => (String[])this.group.gr_mem.Clone();
{
return (string[]) group.gr_mem.Clone ();
}
public override int GetHashCode () public override Int32 GetHashCode() => this.group.GetHashCode();
{
return group.GetHashCode ();
}
public override bool Equals (object obj) public override Boolean Equals(Object obj) => obj == null || this.GetType() != obj.GetType() ? false : this.group.Equals(((UnixGroupInfo)obj).group);
{
if (obj == null || GetType () != obj.GetType())
return false;
return group.Equals (((UnixGroupInfo) obj).group);
}
public override string ToString () public override String ToString() => this.group.ToString();
{
return group.ToString();
}
public Native.Group ToGroup () public Native.Group ToGroup() => CopyGroup(this.group);
{
return CopyGroup (group);
}
public static UnixGroupInfo[] GetLocalGroups () public static UnixGroupInfo[] GetLocalGroups ()
{ {
ArrayList entries = new ArrayList (); ArrayList entries = new ArrayList ();
lock (Native.Syscall.grp_lock) { lock (Native.Syscall.grp_lock) {
if (Native.Syscall.setgrent () != 0) if (Native.Syscall.setgrent () != 0) {
UnixMarshal.ThrowExceptionForLastError ();
try {
Native.Group g;
while ((g = Native.Syscall.getgrent()) != null)
entries.Add (new UnixGroupInfo (g));
if (Native.Syscall.GetLastError() != (Native.Errno) 0)
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
} }
try {
Native.Group g;
while ((g = Native.Syscall.getgrent()) != null) {
_ = entries.Add(new UnixGroupInfo(g));
}
if (Native.Syscall.GetLastError() != (Native.Errno) 0) {
UnixMarshal.ThrowExceptionForLastError ();
}
}
finally { finally {
Native.Syscall.endgrent (); _ = Native.Syscall.endgrent();
} }
} }
return (UnixGroupInfo[]) entries.ToArray (typeof(UnixGroupInfo)); return (UnixGroupInfo[]) entries.ToArray (typeof(UnixGroupInfo));

View File

@ -30,75 +30,49 @@ using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Mono.Unix;
namespace Mono.Unix { namespace Mono.Unix {
[Serializable] [Serializable]
public class UnixIOException : IOException public class UnixIOException : IOException
{ {
private int errno; private Int32 errno;
public UnixIOException () public UnixIOException ()
: this (Marshal.GetLastWin32Error()) : this (Marshal.GetLastWin32Error())
{} {}
public UnixIOException (int errno) public UnixIOException(Int32 errno)
: base (GetMessage (Native.NativeConvert.ToErrno (errno))) : base(GetMessage(Native.NativeConvert.ToErrno(errno))) => this.errno = errno;
{
this.errno = errno;
}
public UnixIOException (int errno, Exception inner) public UnixIOException(Int32 errno, Exception inner)
: base (GetMessage (Native.NativeConvert.ToErrno (errno)), inner) : base(GetMessage(Native.NativeConvert.ToErrno(errno)), inner) => this.errno = errno;
{
this.errno = errno;
}
public UnixIOException (Native.Errno errno) public UnixIOException(Native.Errno errno)
: base (GetMessage (errno)) : base(GetMessage(errno)) => this.errno = Native.NativeConvert.FromErrno(errno);
{
this.errno = Native.NativeConvert.FromErrno (errno);
}
public UnixIOException (Native.Errno errno, Exception inner) public UnixIOException(Native.Errno errno, Exception inner)
: base (GetMessage (errno), inner) : base(GetMessage(errno), inner) => this.errno = Native.NativeConvert.FromErrno(errno);
{
this.errno = Native.NativeConvert.FromErrno (errno);
}
public UnixIOException (string message) public UnixIOException(String message)
: base (message) : base(message) => this.errno = 0;
{
this.errno = 0;
}
public UnixIOException (string message, Exception inner) public UnixIOException(String message, Exception inner)
: base (message, inner) : base(message, inner) => this.errno = 0;
{
this.errno = 0;
}
protected UnixIOException (SerializationInfo info, StreamingContext context) protected UnixIOException (SerializationInfo info, StreamingContext context)
: base (info, context) : base (info, context)
{ {
} }
public int NativeErrorCode { public Int32 NativeErrorCode => this.errno;
get {return errno;}
}
public Native.Errno ErrorCode { public Native.Errno ErrorCode => Native.NativeConvert.ToErrno(this.errno);
get {return Native.NativeConvert.ToErrno (errno);}
}
private static string GetMessage (Native.Errno errno) private static String GetMessage(Native.Errno errno) => String.Format("{0} [{1}].",
{ UnixMarshal.GetErrorDescription(errno),
return string.Format ("{0} [{1}].",
UnixMarshal.GetErrorDescription (errno),
errno); errno);
} }
}
} }
// vim: noexpandtab // vim: noexpandtab

View File

@ -36,15 +36,15 @@ using System.IO;
namespace Mono.Unix { namespace Mono.Unix {
public class UnixListener : MarshalByRefObject, IDisposable { public class UnixListener : MarshalByRefObject, IDisposable {
bool disposed; Boolean disposed;
bool listening; Boolean listening;
Socket server; Socket server;
EndPoint savedEP; EndPoint savedEP;
void Init (UnixEndPoint ep) void Init (UnixEndPoint ep)
{ {
listening = false; this.listening = false;
string filename = ep.Filename; String filename = ep.Filename;
if (File.Exists (filename)) { if (File.Exists (filename)) {
Socket conn = new Socket (AddressFamily.Unix, SocketType.Stream, 0); Socket conn = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
try { try {
@ -56,117 +56,119 @@ namespace Mono.Unix {
File.Delete (filename); File.Delete (filename);
} }
server = new Socket (AddressFamily.Unix, SocketType.Stream, 0); this.server = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
server.Bind (ep); this.server.Bind (ep);
savedEP = server.LocalEndPoint; this.savedEP = this.server.LocalEndPoint;
} }
public UnixListener (string path) public UnixListener (String path)
{ {
if (!Directory.Exists (Path.GetDirectoryName (path))) if (!Directory.Exists (Path.GetDirectoryName (path))) {
Directory.CreateDirectory (Path.GetDirectoryName (path)); _ = Directory.CreateDirectory(Path.GetDirectoryName(path));
}
Init (new UnixEndPoint (path)); this.Init (new UnixEndPoint (path));
} }
public UnixListener (UnixEndPoint localEndPoint) public UnixListener (UnixEndPoint localEndPoint)
{ {
if (localEndPoint == null) if (localEndPoint == null) {
throw new ArgumentNullException ("localendPoint"); throw new ArgumentNullException ("localendPoint");
Init (localEndPoint);
} }
public EndPoint LocalEndpoint { this.Init (localEndPoint);
get { return savedEP; }
} }
protected Socket Server { public EndPoint LocalEndpoint => this.savedEP;
get { return server; }
} protected Socket Server => this.server;
public Socket AcceptSocket () public Socket AcceptSocket ()
{ {
CheckDisposed (); this.CheckDisposed ();
if (!listening) if (!this.listening) {
throw new InvalidOperationException ("Socket is not listening"); throw new InvalidOperationException ("Socket is not listening");
}
return server.Accept (); return this.server.Accept ();
} }
public UnixClient AcceptUnixClient () public UnixClient AcceptUnixClient ()
{ {
CheckDisposed (); this.CheckDisposed ();
if (!listening) if (!this.listening) {
throw new InvalidOperationException ("Socket is not listening"); throw new InvalidOperationException ("Socket is not listening");
}
return new UnixClient (AcceptSocket ()); return new UnixClient (this.AcceptSocket ());
} }
~UnixListener () ~UnixListener ()
{ {
Dispose (false); this.Dispose (false);
} }
public bool Pending () public Boolean Pending ()
{ {
CheckDisposed (); this.CheckDisposed ();
if (!listening) if (!this.listening) {
throw new InvalidOperationException ("Socket is not listening"); throw new InvalidOperationException ("Socket is not listening");
return server.Poll (1000, SelectMode.SelectRead);
} }
public void Start () return this.server.Poll (1000, SelectMode.SelectRead);
{
Start (5);
} }
public void Start (int backlog) public void Start() => this.Start(5);
public void Start (Int32 backlog)
{ {
CheckDisposed (); this.CheckDisposed ();
if (listening) if (this.listening) {
return; return;
}
server.Listen (backlog); this.server.Listen (backlog);
listening = true; this.listening = true;
} }
public void Stop () public void Stop ()
{ {
CheckDisposed (); this.CheckDisposed ();
Dispose (true); this.Dispose (true);
} }
public void Dispose () public void Dispose ()
{ {
Dispose (true); this.Dispose (true);
GC.SuppressFinalize (this); GC.SuppressFinalize (this);
} }
protected void Dispose (bool disposing) protected void Dispose (Boolean disposing)
{ {
if (disposed) if (this.disposed) {
return; return;
}
if (disposing) { if (disposing) {
try { try {
File.Delete (((UnixEndPoint) savedEP).Filename); File.Delete (((UnixEndPoint)this.savedEP).Filename);
} catch { } catch {
} }
if (server != null) if (this.server != null) {
server.Close (); this.server.Close ();
server = null;
} }
disposed = true; this.server = null;
}
this.disposed = true;
} }
void CheckDisposed () void CheckDisposed ()
{ {
if (disposed) if (this.disposed) {
throw new ObjectDisposedException (GetType().FullName); throw new ObjectDisposedException (this.GetType().FullName);
}
} }
} }

View File

@ -27,6 +27,7 @@
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -55,7 +56,7 @@ namespace Mono.Unix {
// be thread-safe between managed & unmanaged code. // be thread-safe between managed & unmanaged code.
internal class ErrorMarshal internal class ErrorMarshal
{ {
internal delegate string ErrorTranslator (Native.Errno errno); internal delegate String ErrorTranslator (Native.Errno errno);
internal static readonly ErrorTranslator Translate; internal static readonly ErrorTranslator Translate;
@ -63,30 +64,27 @@ namespace Mono.Unix {
{ {
try { try {
Translate = new ErrorTranslator (strerror_r); Translate = new ErrorTranslator (strerror_r);
Translate (Native.Errno.ERANGE); _ = Translate(Native.Errno.ERANGE);
} }
catch (EntryPointNotFoundException) { catch (EntryPointNotFoundException) {
Translate = new ErrorTranslator (strerror); Translate = new ErrorTranslator (strerror);
} }
} }
private static string strerror (Native.Errno errno) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
{ private static String strerror(Native.Errno errno) => Native.Stdlib.strerror(errno);
return Native.Stdlib.strerror (errno);
}
private static string strerror_r (Native.Errno errno) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static String strerror_r (Native.Errno errno)
{ {
StringBuilder buf = new StringBuilder (16); StringBuilder buf = new StringBuilder (16);
int r = 0; Int32 r;
do { do {
buf.Capacity *= 2; buf.Capacity *= 2;
r = Native.Syscall.strerror_r (errno, buf); r = Native.Syscall.strerror_r (errno, buf);
} while (r == -1 && Native.Stdlib.GetLastError() == Native.Errno.ERANGE); } while (r == -1 && Native.Stdlib.GetLastError() == Native.Errno.ERANGE);
if (r == -1) return r == -1 ? "** Unknown error code: " + (Int32) errno + "**" : buf.ToString();
return "** Unknown error code: " + ((int) errno) + "**";
return buf.ToString();
} }
} }
@ -94,141 +92,129 @@ namespace Mono.Unix {
{ {
private UnixMarshal () {} private UnixMarshal () {}
[CLSCompliant (false)] //[CLSCompliant(false)]
public static string GetErrorDescription (Native.Errno errno) public static String GetErrorDescription(Native.Errno errno) => ErrorMarshal.Translate(errno);
{
return ErrorMarshal.Translate (errno);
}
public static IntPtr AllocHeap (long size) public static IntPtr AllocHeap (Int64 size)
{ {
if (size < 0) if (size < 0) {
throw new ArgumentOutOfRangeException ("size", "< 0"); throw new ArgumentOutOfRangeException ("size", "< 0");
return Native.Stdlib.malloc ((ulong) size);
} }
public static IntPtr ReAllocHeap (IntPtr ptr, long size) return Native.Stdlib.malloc ((UInt64) size);
}
public static IntPtr ReAllocHeap (IntPtr ptr, Int64 size)
{ {
if (size < 0) if (size < 0) {
throw new ArgumentOutOfRangeException ("size", "< 0"); throw new ArgumentOutOfRangeException ("size", "< 0");
return Native.Stdlib.realloc (ptr, (ulong) size);
} }
public static void FreeHeap (IntPtr ptr) return Native.Stdlib.realloc (ptr, (UInt64) size);
{
Native.Stdlib.free (ptr);
} }
public static unsafe string PtrToStringUnix (IntPtr p) public static void FreeHeap(IntPtr ptr) => Native.Stdlib.free(ptr);
public static unsafe String PtrToStringUnix (IntPtr p)
{ {
if (p == IntPtr.Zero) if (p == IntPtr.Zero) {
return null; return null;
int len = checked ((int) Native.Stdlib.strlen (p));
return new string ((sbyte*) p, 0, len, UnixEncoding.Instance);
} }
public static string PtrToString (IntPtr p) Int32 len = checked ((Int32) Native.Stdlib.strlen (p));
{ return new String((SByte*) p, 0, len, UnixEncoding.Instance);
if (p == IntPtr.Zero)
return null;
return PtrToString (p, UnixEncoding.Instance);
} }
public static unsafe string PtrToString (IntPtr p, Encoding encoding) public static String PtrToString(IntPtr p) => p == IntPtr.Zero ? null : PtrToString(p, UnixEncoding.Instance);
{
if (p == IntPtr.Zero)
return null;
if (encoding == null) public static unsafe String PtrToString (IntPtr p, Encoding encoding)
{
if (p == IntPtr.Zero) {
return null;
}
if (encoding == null) {
throw new ArgumentNullException ("encoding"); throw new ArgumentNullException ("encoding");
}
int len = GetStringByteLength (p, encoding); Int32 len = GetStringByteLength (p, encoding);
// Due to variable-length encoding schemes, GetStringByteLength() may // Due to variable-length encoding schemes, GetStringByteLength() may
// have returned multiple "null" characters. (For example, when // have returned multiple "null" characters. (For example, when
// encoding a string into UTF-8 there will be 4 terminating nulls.) // encoding a string into UTF-8 there will be 4 terminating nulls.)
// We don't want these null's to be in the returned string, so strip // We don't want these null's to be in the returned string, so strip
// them off. // them off.
string s = new string ((sbyte*) p, 0, len, encoding); String s = new String((SByte*) p, 0, len, encoding);
len = s.Length; len = s.Length;
while (len > 0 && s [len-1] == 0) while (len > 0 && s [len-1] == 0) {
--len; --len;
if (len == s.Length)
return s;
return s.Substring (0, len);
} }
private static int GetStringByteLength (IntPtr p, Encoding encoding) return len == s.Length ? s : s.Substring (0, len);
}
private static Int32 GetStringByteLength (IntPtr p, Encoding encoding)
{ {
Type encodingType = encoding.GetType (); Type encodingType = encoding.GetType ();
int len = -1; Int32 len = typeof(UTF8Encoding).IsAssignableFrom (encodingType) ||
// Encodings that will always end with a single null byte
if (typeof(UTF8Encoding).IsAssignableFrom (encodingType) ||
typeof(UTF7Encoding).IsAssignableFrom (encodingType) || typeof(UTF7Encoding).IsAssignableFrom (encodingType) ||
typeof(UnixEncoding).IsAssignableFrom (encodingType) || typeof(UnixEncoding).IsAssignableFrom (encodingType) ||
typeof(ASCIIEncoding).IsAssignableFrom (encodingType)) { typeof(ASCIIEncoding).IsAssignableFrom (encodingType)
len = checked ((int) Native.Stdlib.strlen (p)); ? (Int32) Native.Stdlib.strlen (p)
} : typeof(UnicodeEncoding).IsAssignableFrom(encodingType)
// Encodings that will always end with a 0x0000 16-bit word ? GetInt16BufferLength(p)
else if (typeof(UnicodeEncoding).IsAssignableFrom (encodingType)) { : typeof(UTF32Encoding).IsAssignableFrom(encodingType)
len = GetInt16BufferLength (p); ? GetInt32BufferLength(p)
} : GetRandomBufferLength(p, encoding.GetMaxByteCount(1));
// Encodings that will always end with a 0x00000000 32-bit word
else if (typeof(UTF32Encoding).IsAssignableFrom (encodingType)) { // Encodings that will always end with a single null byte
len = GetInt32BufferLength (p);
} if(len == -1) {
// Some non-public encoding, such as Latin1 or a DBCS charset. throw new NotSupportedException ("Unable to determine native string buffer length");
// Look for a sequence of encoding.GetMaxByteCount() bytes that are all
// 0, which should be the terminating null.
// This is "iffy", since it may fail for variable-width encodings; for
// example, UTF8Encoding.GetMaxByteCount(1) = 4, so this would read 3
// bytes past the end of the string, possibly into garbage memory
// (which is why we special case UTF above).
else {
len = GetRandomBufferLength (p, encoding.GetMaxByteCount(1));
} }
if (len == -1)
throw new NotSupportedException ("Unable to determine native string buffer length");
return len; return len;
} }
private static int GetInt16BufferLength (IntPtr p) private static Int32 GetInt16BufferLength (IntPtr p)
{ {
int len = 0; Int32 len = 0;
while (Marshal.ReadInt16 (p, len*2) != 0) while (Marshal.ReadInt16 (p, len*2) != 0) {
checked {++len;} checked {++len;}
}
return checked(len*2); return checked(len*2);
} }
private static int GetInt32BufferLength (IntPtr p) private static Int32 GetInt32BufferLength (IntPtr p)
{ {
int len = 0; Int32 len = 0;
while (Marshal.ReadInt32 (p, len*4) != 0) while (Marshal.ReadInt32 (p, len*4) != 0) {
checked {++len;} checked {++len;}
}
return checked(len*4); return checked(len*4);
} }
private static int GetRandomBufferLength (IntPtr p, int nullLength) private static Int32 GetRandomBufferLength (IntPtr p, Int32 nullLength)
{ {
switch (nullLength) { switch (nullLength) {
case 1: return checked ((int) Native.Stdlib.strlen (p)); case 1: return checked ((Int32) Native.Stdlib.strlen (p));
case 2: return GetInt16BufferLength (p); case 2: return GetInt16BufferLength (p);
case 4: return GetInt32BufferLength (p); case 4: return GetInt32BufferLength (p);
} }
int len = 0; Int32 len = 0;
int num_null_seen = 0; Int32 num_null_seen = 0;
do { do {
byte b = Marshal.ReadByte (p, len++); Byte b = Marshal.ReadByte (p, len++);
if (b == 0) if (b == 0) {
++num_null_seen; ++num_null_seen;
else } else {
num_null_seen = 0; num_null_seen = 0;
}
} while (num_null_seen != nullLength); } while (num_null_seen != nullLength);
return len; return len;
@ -248,25 +234,25 @@ namespace Mono.Unix {
* The terminating NULL is required so that we know when to stop looking * The terminating NULL is required so that we know when to stop looking
* for strings. * for strings.
*/ */
public static string[] PtrToStringArray (IntPtr stringArray) public static String[] PtrToStringArray(IntPtr stringArray) => PtrToStringArray(stringArray, UnixEncoding.Instance);
public static String[] PtrToStringArray (IntPtr stringArray, Encoding encoding)
{ {
return PtrToStringArray (stringArray, UnixEncoding.Instance); if (stringArray == IntPtr.Zero) {
return new String[]{};
} }
public static string[] PtrToStringArray (IntPtr stringArray, Encoding encoding) Int32 argc = CountStrings (stringArray);
{
if (stringArray == IntPtr.Zero)
return new string[]{};
int argc = CountStrings (stringArray);
return PtrToStringArray (argc, stringArray, encoding); return PtrToStringArray (argc, stringArray, encoding);
} }
private static int CountStrings (IntPtr stringArray) private static Int32 CountStrings (IntPtr stringArray)
{ {
int count = 0; Int32 count = 0;
while (Marshal.ReadIntPtr (stringArray, count*IntPtr.Size) != IntPtr.Zero) while (Marshal.ReadIntPtr (stringArray, count*IntPtr.Size) != IntPtr.Zero) {
++count; ++count;
}
return count; return count;
} }
@ -279,22 +265,24 @@ namespace Mono.Unix {
* stringArray[count] is NOT accessed (though ANSI C requires that * stringArray[count] is NOT accessed (though ANSI C requires that
* argv[argc] = NULL, which PtrToStringArray(IntPtr) requires). * argv[argc] = NULL, which PtrToStringArray(IntPtr) requires).
*/ */
public static string[] PtrToStringArray (int count, IntPtr stringArray) public static String[] PtrToStringArray(Int32 count, IntPtr stringArray) => PtrToStringArray(count, stringArray, UnixEncoding.Instance);
public static String[] PtrToStringArray (Int32 count, IntPtr stringArray, Encoding encoding)
{ {
return PtrToStringArray (count, stringArray, UnixEncoding.Instance); if (count < 0) {
throw new ArgumentOutOfRangeException ("count", "< 0");
} }
public static string[] PtrToStringArray (int count, IntPtr stringArray, Encoding encoding) if (encoding == null) {
{
if (count < 0)
throw new ArgumentOutOfRangeException ("count", "< 0");
if (encoding == null)
throw new ArgumentNullException ("encoding"); throw new ArgumentNullException ("encoding");
if (stringArray == IntPtr.Zero) }
return new string[count];
string[] members = new string[count]; if (stringArray == IntPtr.Zero) {
for (int i = 0; i < count; ++i) { return new String[count];
}
String[] members = new String[count];
for (Int32 i = 0; i < count; ++i) {
IntPtr s = Marshal.ReadIntPtr (stringArray, i * IntPtr.Size); IntPtr s = Marshal.ReadIntPtr (stringArray, i * IntPtr.Size);
members[i] = PtrToString (s, encoding); members[i] = PtrToString (s, encoding);
} }
@ -302,51 +290,44 @@ namespace Mono.Unix {
return members; return members;
} }
public static IntPtr StringToHeap (string s) public static IntPtr StringToHeap(String s) => StringToHeap(s, UnixEncoding.Instance);
{
return StringToHeap (s, UnixEncoding.Instance);
}
public static IntPtr StringToHeap (string s, Encoding encoding) public static IntPtr StringToHeap(String s, Encoding encoding) => s == null ? IntPtr.Zero : StringToHeap(s, 0, s.Length, encoding);
public static IntPtr StringToHeap(String s, Int32 index, Int32 count) => StringToHeap(s, index, count, UnixEncoding.Instance);
public static IntPtr StringToHeap (String s, Int32 index, Int32 count, Encoding encoding)
{ {
if (s == null) if (s == null) {
return IntPtr.Zero; return IntPtr.Zero;
return StringToHeap (s, 0, s.Length, encoding);
} }
public static IntPtr StringToHeap (string s, int index, int count) if (encoding == null) {
{
return StringToHeap (s, index, count, UnixEncoding.Instance);
}
public static IntPtr StringToHeap (string s, int index, int count, Encoding encoding)
{
if (s == null)
return IntPtr.Zero;
if (encoding == null)
throw new ArgumentNullException ("encoding"); throw new ArgumentNullException ("encoding");
}
if (index < 0 || count < 0) if (index < 0 || count < 0) {
throw new ArgumentOutOfRangeException ((index < 0 ? "index" : "count"), throw new ArgumentOutOfRangeException (index < 0 ? "index" : "count",
"Non - negative number required."); "Non - negative number required.");
}
if (s.Length - index < count) if (s.Length - index < count) {
throw new ArgumentOutOfRangeException ("s", "Index and count must refer to a location within the string."); throw new ArgumentOutOfRangeException ("s", "Index and count must refer to a location within the string.");
}
int null_terminator_count = encoding.GetMaxByteCount (1); Int32 null_terminator_count = encoding.GetMaxByteCount (1);
int length_without_null = encoding.GetByteCount (s); Int32 length_without_null = encoding.GetByteCount (s);
int marshalLength = checked (length_without_null + null_terminator_count); Int32 marshalLength = checked (length_without_null + null_terminator_count);
IntPtr mem = AllocHeap (marshalLength); IntPtr mem = AllocHeap (marshalLength);
if (mem == IntPtr.Zero) if (mem == IntPtr.Zero) {
throw new UnixIOException (Native.Errno.ENOMEM); throw new UnixIOException (Native.Errno.ENOMEM);
}
unsafe { unsafe {
fixed (char* p = s) { fixed (Char* p = s) {
byte* marshal = (byte*)mem; Byte* marshal = (Byte*)mem;
int bytes_copied; Int32 bytes_copied;
try { try {
bytes_copied = encoding.GetBytes (p + index, count, marshal, marshalLength); bytes_copied = encoding.GetBytes (p + index, count, marshal, marshalLength);
@ -361,70 +342,70 @@ namespace Mono.Unix {
} }
marshal += length_without_null; marshal += length_without_null;
for (int i = 0; i < null_terminator_count; ++i) for (Int32 i = 0; i < null_terminator_count; ++i) {
marshal[i] = 0; marshal[i] = 0;
} }
} }
}
return mem; return mem;
} }
public static bool ShouldRetrySyscall (int r) public static Boolean ShouldRetrySyscall(Int32 r) => r == -1 && Native.Stdlib.GetLastError() == Native.Errno.EINTR;
{
if (r == -1 && Native.Stdlib.GetLastError () == Native.Errno.EINTR)
return true;
return false;
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public static bool ShouldRetrySyscall (int r, out Native.Errno errno) public static Boolean ShouldRetrySyscall (Int32 r, out Native.Errno errno)
{ {
errno = (Native.Errno) 0; errno = (Native.Errno) 0;
if (r == -1 && (errno = Native.Stdlib.GetLastError ()) == Native.Errno.EINTR) return r == -1 && (errno = Native.Stdlib.GetLastError ()) == Native.Errno.EINTR;
return true;
return false;
} }
// we can't permit any printf(3)-style formatting information, since that // we can't permit any printf(3)-style formatting information, since that
// would kill the stack. However, replacing %% is silly, and some %* are // would kill the stack. However, replacing %% is silly, and some %* are
// permitted (such as %m in syslog to print strerror(errno)). // permitted (such as %m in syslog to print strerror(errno)).
internal static string EscapeFormatString (string message, internal static String EscapeFormatString (String message,
char [] permitted) Char[] permitted)
{ {
if (message == null) if (message == null) {
return ""; return "";
}
StringBuilder sb = new StringBuilder (message.Length); StringBuilder sb = new StringBuilder (message.Length);
for (int i = 0; i < message.Length; ++i) { for (Int32 i = 0; i < message.Length; ++i) {
char c = message [i]; Char c = message [i];
sb.Append (c); _ = sb.Append(c);
if (c == '%' && (i+1) < message.Length) { if (c == '%' && i+1 < message.Length) {
char n = message [i+1]; Char n = message [i+1];
if (n == '%' || IsCharPresent (permitted, n)) _ = n == '%' || IsCharPresent (permitted, n) ? sb.Append(n) : sb.Append('%').Append(n);
sb.Append (n);
else
sb.Append ('%').Append (n);
++i; ++i;
} }
// invalid format string: % at EOS. // invalid format string: % at EOS.
else if (c == '%') else if (c == '%') {
sb.Append ('%'); _ = sb.Append('%');
}
} }
return sb.ToString (); return sb.ToString ();
} }
private static bool IsCharPresent (char[] array, char c) private static Boolean IsCharPresent (Char[] array, Char c)
{ {
if (array == null) if (array == null) {
return false; return false;
for (int i = 0; i < array.Length; ++i) }
if (array [i] == c)
for (Int32 i = 0; i < array.Length; ++i) {
if (array [i] == c) {
return true; return true;
}
}
return false; return false;
} }
internal static Exception CreateExceptionForError (Native.Errno errno) internal static Exception CreateExceptionForError (Native.Errno errno)
{ {
string message = GetErrorDescription (errno); String message = GetErrorDescription (errno);
UnixIOException p = new UnixIOException (errno); UnixIOException p = new UnixIOException (errno);
// Ordering: Order alphabetically by exception first (right column), // Ordering: Order alphabetically by exception first (right column),
@ -462,35 +443,28 @@ namespace Mono.Unix {
return p; return p;
} }
internal static Exception CreateExceptionForLastError () internal static Exception CreateExceptionForLastError() => CreateExceptionForError(Native.Stdlib.GetLastError());
{
return CreateExceptionForError (Native.Stdlib.GetLastError());
}
[CLSCompliant (false)] //[CLSCompliant(false)]
public static void ThrowExceptionForError (Native.Errno errno) public static void ThrowExceptionForError(Native.Errno errno) => throw CreateExceptionForError(errno);
{
throw CreateExceptionForError (errno);
}
public static void ThrowExceptionForLastError () public static void ThrowExceptionForLastError() => throw CreateExceptionForLastError();
{
throw CreateExceptionForLastError ();
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public static void ThrowExceptionForErrorIf (int retval, Native.Errno errno) public static void ThrowExceptionForErrorIf (Int32 retval, Native.Errno errno)
{ {
if (retval == -1) if (retval == -1) {
ThrowExceptionForError (errno); ThrowExceptionForError (errno);
} }
}
public static void ThrowExceptionForLastErrorIf (int retval) public static void ThrowExceptionForLastErrorIf (Int32 retval)
{ {
if (retval == -1) if (retval == -1) {
ThrowExceptionForLastError (); ThrowExceptionForLastError ();
} }
} }
}
} }
// vim: noexpandtab // vim: noexpandtab

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;
using Mono.Unix; using Mono.Unix;
@ -37,34 +38,40 @@ namespace Mono.Unix {
{ {
private UnixPath () {} private UnixPath () {}
public static readonly char DirectorySeparatorChar = '/'; public static readonly Char DirectorySeparatorChar = '/';
public static readonly char AltDirectorySeparatorChar = '/'; public static readonly Char AltDirectorySeparatorChar = '/';
public static readonly char PathSeparator = ':'; public static readonly Char PathSeparator = ':';
public static readonly char VolumeSeparatorChar = '/'; public static readonly Char VolumeSeparatorChar = '/';
private static readonly char[] _InvalidPathChars = new char[]{}; private static readonly Char[] _InvalidPathChars = new Char[]{};
public static char[] GetInvalidPathChars () public static Char[] GetInvalidPathChars() => (Char[])_InvalidPathChars.Clone();
public static String Combine (String path1, params String[] paths)
{ {
return (char[]) _InvalidPathChars.Clone (); if (path1 == null) {
throw new ArgumentNullException ("path1");
} }
public static string Combine (string path1, params string[] paths) if (paths == null) {
{
if (path1 == null)
throw new ArgumentNullException ("path1");
if (paths == null)
throw new ArgumentNullException ("paths"); throw new ArgumentNullException ("paths");
if (path1.IndexOfAny (_InvalidPathChars) != -1) }
throw new ArgumentException ("Illegal characters in path", "path1");
int len = path1.Length; if (path1.IndexOfAny (_InvalidPathChars) != -1) {
int start = -1; throw new ArgumentException ("Illegal characters in path", "path1");
for (int i = 0; i < paths.Length; ++i) { }
if (paths [i] == null)
Int32 len = path1.Length;
Int32 start = -1;
for (Int32 i = 0; i < paths.Length; ++i) {
if (paths [i] == null) {
throw new ArgumentNullException ("paths[" + i + "]"); throw new ArgumentNullException ("paths[" + i + "]");
if (paths [i].IndexOfAny (_InvalidPathChars) != -1) }
if (paths [i].IndexOfAny (_InvalidPathChars) != -1) {
throw new ArgumentException ("Illegal characters in path", "paths[" + i + "]"); throw new ArgumentException ("Illegal characters in path", "paths[" + i + "]");
}
if (IsPathRooted (paths [i])) { if (IsPathRooted (paths [i])) {
len = 0; len = 0;
start = i; start = i;
@ -74,133 +81,132 @@ namespace Mono.Unix {
StringBuilder sb = new StringBuilder (len); StringBuilder sb = new StringBuilder (len);
if (start == -1) { if (start == -1) {
sb.Append (path1); _ = sb.Append(path1);
start = 0; start = 0;
} }
for (int i = start; i < paths.Length; ++i) for (Int32 i = start; i < paths.Length; ++i) {
Combine (sb, paths [i]); Combine (sb, paths [i]);
}
return sb.ToString (); return sb.ToString ();
} }
private static void Combine (StringBuilder path, string part) private static void Combine (StringBuilder path, String part)
{ {
if (path.Length > 0 && part.Length > 0) { if (path.Length > 0 && part.Length > 0) {
char end = path [path.Length-1]; Char end = path [path.Length-1];
if (end != DirectorySeparatorChar && if (end != DirectorySeparatorChar &&
end != AltDirectorySeparatorChar && end != AltDirectorySeparatorChar &&
end != VolumeSeparatorChar) end != VolumeSeparatorChar) {
path.Append (DirectorySeparatorChar); _ = path.Append(DirectorySeparatorChar);
} }
path.Append (part); }
_ = path.Append(part);
} }
public static string GetDirectoryName (string path) public static String GetDirectoryName (String path)
{ {
CheckPath (path); CheckPath (path);
int lastDir = path.LastIndexOf (DirectorySeparatorChar); Int32 lastDir = path.LastIndexOf (DirectorySeparatorChar);
if (lastDir > 0) return lastDir > 0 ? path.Substring (0, lastDir) : lastDir == 0 ? "/" : "";
return path.Substring (0, lastDir);
if (lastDir == 0)
return "/";
return "";
} }
public static string GetFileName (string path) public static String GetFileName (String path)
{ {
if (path == null || path.Length == 0) if (path == null || path.Length == 0) {
return path;
int lastDir = path.LastIndexOf (DirectorySeparatorChar);
if (lastDir >= 0)
return path.Substring (lastDir+1);
return path; return path;
} }
public static string GetFullPath (string path) Int32 lastDir = path.LastIndexOf (DirectorySeparatorChar);
return lastDir >= 0 ? path.Substring (lastDir+1) : path;
}
public static String GetFullPath (String path)
{ {
path = _GetFullPath (path); path = _GetFullPath (path);
return GetCanonicalPath (path); return GetCanonicalPath (path);
} }
private static string _GetFullPath (string path) [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static String _GetFullPath (String path)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException ("path"); throw new ArgumentNullException ("path");
if (!IsPathRooted (path)) }
if (!IsPathRooted (path)) {
path = UnixDirectoryInfo.GetCurrentDirectory() + DirectorySeparatorChar + path; path = UnixDirectoryInfo.GetCurrentDirectory() + DirectorySeparatorChar + path;
}
return path; return path;
} }
public static string GetCanonicalPath (string path) public static String GetCanonicalPath (String path)
{ {
string [] dirs; GetPathComponents(path, out String[] dirs, out Int32 lastIndex);
int lastIndex; String end = String.Join ("/", dirs, 0, lastIndex);
GetPathComponents (path, out dirs, out lastIndex);
string end = string.Join ("/", dirs, 0, lastIndex);
return IsPathRooted (path) ? "/" + end : end; return IsPathRooted (path) ? "/" + end : end;
} }
private static void GetPathComponents (string path, private static void GetPathComponents (String path,
out string[] components, out int lastIndex) out String[] components, out Int32 lastIndex)
{ {
string [] dirs = path.Split (DirectorySeparatorChar); String[] dirs = path.Split (DirectorySeparatorChar);
int target = 0; Int32 target = 0;
for (int i = 0; i < dirs.Length; ++i) { for (Int32 i = 0; i < dirs.Length; ++i) {
if (dirs [i] == "." || dirs [i] == string.Empty) continue; if (dirs [i] == "." || dirs [i] == String.Empty) {
else if (dirs [i] == "..") { continue;
if (target != 0) --target; } else if (dirs [i] == "..") {
else ++target; if (target != 0) {
--target;
} else {
++target;
} }
else }
else {
dirs [target++] = dirs [i]; dirs [target++] = dirs [i];
} }
}
components = dirs; components = dirs;
lastIndex = target; lastIndex = target;
} }
public static string GetPathRoot (string path) public static String GetPathRoot(String path) => path == null ? null : !IsPathRooted(path) ? "" : "/";
public static String GetCompleteRealPath (String path)
{ {
if (path == null) if (path == null) {
return null; throw new ArgumentNullException ("path");
if (!IsPathRooted (path))
return "";
return "/";
} }
public static string GetCompleteRealPath (string path) GetPathComponents(path, out String[] dirs, out Int32 lastIndex);
{
if (path == null)
throw new ArgumentNullException ("path");
string [] dirs;
int lastIndex;
GetPathComponents (path, out dirs, out lastIndex);
StringBuilder realPath = new StringBuilder (); StringBuilder realPath = new StringBuilder ();
if (dirs.Length > 0) { if (dirs.Length > 0) {
string dir = IsPathRooted (path) ? "/" : ""; String dir = IsPathRooted (path) ? "/" : "";
dir += dirs [0]; dir += dirs [0];
realPath.Append (GetRealPath (dir)); _ = realPath.Append(GetRealPath(dir));
} }
for (int i = 1; i < lastIndex; ++i) { for (Int32 i = 1; i < lastIndex; ++i) {
realPath.Append ("/").Append (dirs [i]); _ = realPath.Append("/").Append(dirs[i]);
string p = GetRealPath (realPath.ToString()); String p = GetRealPath (realPath.ToString());
realPath.Remove (0, realPath.Length); _ = realPath.Remove(0, realPath.Length);
realPath.Append (p); _ = realPath.Append(p);
} }
return realPath.ToString (); return realPath.ToString ();
} }
public static string GetRealPath (string path) public static String GetRealPath (String path)
{ {
do { do {
string name = ReadSymbolicLink (path); String name = ReadSymbolicLink (path);
if (name == null) if (name == null) {
return path; return path;
if (IsPathRooted (name)) }
if (IsPathRooted (name)) {
path = name; path = name;
else { } else {
path = GetDirectoryName (path) + DirectorySeparatorChar + name; path = GetDirectoryName (path) + DirectorySeparatorChar + name;
path = GetCanonicalPath (path); path = GetCanonicalPath (path);
} }
@ -209,78 +215,85 @@ namespace Mono.Unix {
// Read the specified symbolic link. If the file isn't a symbolic link, // Read the specified symbolic link. If the file isn't a symbolic link,
// return null; otherwise, return the contents of the symbolic link. // return null; otherwise, return the contents of the symbolic link.
internal static string ReadSymbolicLink (string path) internal static String ReadSymbolicLink (String path)
{ {
string target = TryReadLink (path); String target = TryReadLink (path);
if (target == null) { if (target == null) {
Native.Errno errno = Native.Stdlib.GetLastError (); Native.Errno errno = Native.Stdlib.GetLastError ();
if (errno != Native.Errno.EINVAL) if (errno != Native.Errno.EINVAL) {
UnixMarshal.ThrowExceptionForError (errno); UnixMarshal.ThrowExceptionForError (errno);
} }
}
return target; return target;
} }
public static string TryReadLink (string path) public static String TryReadLink (String path)
{ {
byte[] buf = new byte[256]; Byte[] buf = new Byte[256];
do { do {
long r = Native.Syscall.readlink (path, buf); Int64 r = Native.Syscall.readlink (path, buf);
if (r < 0) if (r < 0) {
return null; return null;
else if (r == buf.Length) } else if (r == buf.Length) {
buf = new byte[checked (buf.LongLength * 2)]; buf = new Byte[checked (buf.LongLength * 2)];
else } else {
return UnixEncoding.Instance.GetString (buf, 0, checked ((int) r)); return UnixEncoding.Instance.GetString (buf, 0, checked ((Int32) r));
}
} while (true); } while (true);
} }
public static string TryReadLinkAt (int dirfd, string path) public static String TryReadLinkAt (Int32 dirfd, String path)
{ {
byte[] buf = new byte[256]; Byte[] buf = new Byte[256];
do { do {
long r = Native.Syscall.readlinkat (dirfd, path, buf); Int64 r = Native.Syscall.readlinkat (dirfd, path, buf);
if (r < 0) if (r < 0) {
return null; return null;
else if (r == buf.Length) } else if (r == buf.Length) {
buf = new byte[checked (buf.LongLength * 2)]; buf = new Byte[checked (buf.LongLength * 2)];
else } else {
return UnixEncoding.Instance.GetString (buf, 0, checked ((int) r)); return UnixEncoding.Instance.GetString (buf, 0, checked ((Int32) r));
}
} while (true); } while (true);
} }
public static string ReadLink (string path) public static String ReadLink (String path)
{ {
string target = TryReadLink (path); String target = TryReadLink (path);
if (target == null) if (target == null) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return target; return target;
} }
public static string ReadLinkAt (int dirfd, string path) public static String ReadLinkAt (Int32 dirfd, String path)
{ {
string target = TryReadLinkAt (dirfd, path); String target = TryReadLinkAt (dirfd, path);
if (target == null) if (target == null) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
}
return target; return target;
} }
public static bool IsPathRooted (string path) public static Boolean IsPathRooted(String path) => path == null || path.Length == 0 ? false : path[0] == DirectorySeparatorChar;
{
if (path == null || path.Length == 0)
return false;
return path [0] == DirectorySeparatorChar;
}
internal static void CheckPath (string path) internal static void CheckPath (String path)
{ {
if (path == null) if (path == null) {
throw new ArgumentNullException (); throw new ArgumentNullException ();
if (path.Length == 0) }
if (path.Length == 0) {
throw new ArgumentException ("Path cannot contain a zero-length string", "path"); throw new ArgumentException ("Path cannot contain a zero-length string", "path");
if (path.IndexOfAny (_InvalidPathChars) != -1) }
if (path.IndexOfAny (_InvalidPathChars) != -1) {
throw new ArgumentException ("Invalid characters in path.", "path"); throw new ArgumentException ("Invalid characters in path.", "path");
} }
} }
}
} }
// vim: noexpandtab // vim: noexpandtab

View File

@ -38,8 +38,8 @@ namespace Mono.Unix {
{ {
public UnixPipes (UnixStream reading, UnixStream writing) public UnixPipes (UnixStream reading, UnixStream writing)
{ {
Reading = reading; this.Reading = reading;
Writing = writing; this.Writing = writing;
} }
public UnixStream Reading; public UnixStream Reading;
@ -47,41 +47,30 @@ namespace Mono.Unix {
public static UnixPipes CreatePipes () public static UnixPipes CreatePipes ()
{ {
int reading, writing; Int32 r = Native.Syscall.pipe(out Int32 reading, out Int32 writing);
int r = Native.Syscall.pipe (out reading, out writing);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return new UnixPipes (new UnixStream (reading), new UnixStream (writing)); return new UnixPipes (new UnixStream (reading), new UnixStream (writing));
} }
public override bool Equals (object value) public override Boolean Equals (Object value)
{ {
if ((value == null) || (value.GetType () != GetType ())) if (value == null || value.GetType () != this.GetType ()) {
return false; return false;
}
UnixPipes other = (UnixPipes) value; UnixPipes other = (UnixPipes) value;
return Reading.Handle == other.Reading.Handle && return this.Reading.Handle == other.Reading.Handle &&
Writing.Handle == other.Writing.Handle; this.Writing.Handle == other.Writing.Handle;
} }
public bool Equals (UnixPipes value) public Boolean Equals(UnixPipes value) => this.Reading.Handle == value.Reading.Handle &&
{ this.Writing.Handle == value.Writing.Handle;
return Reading.Handle == value.Reading.Handle &&
Writing.Handle == value.Writing.Handle;
}
public override int GetHashCode () public override Int32 GetHashCode() => this.Reading.Handle.GetHashCode() ^ this.Writing.Handle.GetHashCode();
{
return Reading.Handle.GetHashCode () ^ Writing.Handle.GetHashCode ();
}
public static bool operator== (UnixPipes lhs, UnixPipes rhs) public static Boolean operator ==(UnixPipes lhs, UnixPipes rhs) => lhs.Equals(rhs);
{
return lhs.Equals (rhs);
}
public static bool operator!= (UnixPipes lhs, UnixPipes rhs) public static Boolean operator !=(UnixPipes lhs, UnixPipes rhs) => !lhs.Equals(rhs);
{
return !lhs.Equals (rhs);
}
} }
} }

View File

@ -33,121 +33,111 @@ namespace Mono.Unix {
public sealed class UnixProcess public sealed class UnixProcess
{ {
private int pid; private Int32 pid;
internal UnixProcess (int pid) internal UnixProcess(Int32 pid) => this.pid = pid;
{
this.pid = pid;
}
public int Id { public Int32 Id => this.pid;
get {return pid;}
}
public bool HasExited { public Boolean HasExited {
get { get {
int status = GetProcessStatus (); Int32 status = this.GetProcessStatus ();
return Native.Syscall.WIFEXITED (status); return Native.Syscall.WIFEXITED (status);
} }
} }
private int GetProcessStatus () private Int32 GetProcessStatus ()
{ {
int status; Int32 r = Native.Syscall.waitpid(this.pid, out Int32 status,
int r = Native.Syscall.waitpid (pid, out status,
Native.WaitOptions.WNOHANG | Native.WaitOptions.WUNTRACED); Native.WaitOptions.WNOHANG | Native.WaitOptions.WUNTRACED);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return r; return r;
} }
public int ExitCode { public Int32 ExitCode {
get { get {
if (!HasExited) if (!this.HasExited) {
throw new InvalidOperationException ( throw new InvalidOperationException (
Locale.GetText ("Process hasn't exited")); Locale.GetText ("Process hasn't exited"));
int status = GetProcessStatus (); }
Int32 status = this.GetProcessStatus ();
return Native.Syscall.WEXITSTATUS (status); return Native.Syscall.WEXITSTATUS (status);
} }
} }
public bool HasSignaled { public Boolean HasSignaled {
get { get {
int status = GetProcessStatus (); Int32 status = this.GetProcessStatus ();
return Native.Syscall.WIFSIGNALED (status); return Native.Syscall.WIFSIGNALED (status);
} }
} }
public Native.Signum TerminationSignal { public Native.Signum TerminationSignal {
get { get {
if (!HasSignaled) if (!this.HasSignaled) {
throw new InvalidOperationException ( throw new InvalidOperationException (
Locale.GetText ("Process wasn't terminated by a signal")); Locale.GetText ("Process wasn't terminated by a signal"));
int status = GetProcessStatus (); }
Int32 status = this.GetProcessStatus ();
return Native.Syscall.WTERMSIG (status); return Native.Syscall.WTERMSIG (status);
} }
} }
public bool HasStopped { public Boolean HasStopped {
get { get {
int status = GetProcessStatus (); Int32 status = this.GetProcessStatus ();
return Native.Syscall.WIFSTOPPED (status); return Native.Syscall.WIFSTOPPED (status);
} }
} }
public Native.Signum StopSignal { public Native.Signum StopSignal {
get { get {
if (!HasStopped) if (!this.HasStopped) {
throw new InvalidOperationException ( throw new InvalidOperationException (
Locale.GetText ("Process isn't stopped")); Locale.GetText ("Process isn't stopped"));
int status = GetProcessStatus (); }
Int32 status = this.GetProcessStatus ();
return Native.Syscall.WSTOPSIG (status); return Native.Syscall.WSTOPSIG (status);
} }
} }
public int ProcessGroupId { public Int32 ProcessGroupId {
get {return Native.Syscall.getpgid (pid);} get => Native.Syscall.getpgid(this.pid);
set { set {
int r = Native.Syscall.setpgid (pid, value); Int32 r = Native.Syscall.setpgid(this.pid, value);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf(r);
} }
} }
public int SessionId { public Int32 SessionId {
get { get {
int r = Native.Syscall.getsid (pid); Int32 r = Native.Syscall.getsid (this.pid);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return r; return r;
} }
} }
public static UnixProcess GetCurrentProcess () public static UnixProcess GetCurrentProcess() => new UnixProcess(GetCurrentProcessId());
{
return new UnixProcess (GetCurrentProcessId ());
}
public static int GetCurrentProcessId () public static Int32 GetCurrentProcessId() => Native.Syscall.getpid();
{
return Native.Syscall.getpid ();
}
public void Kill () public void Kill() => this.Signal(Native.Signum.SIGKILL);
{
Signal (Native.Signum.SIGKILL);
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public void Signal (Native.Signum signal) public void Signal (Native.Signum signal)
{ {
int r = Native.Syscall.kill (pid, signal); Int32 r = Native.Syscall.kill (this.pid, signal);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public void WaitForExit () public void WaitForExit ()
{ {
int status; Int32 r;
int r;
do { do {
r = Native.Syscall.waitpid (pid, out status, (Native.WaitOptions) 0); r = Native.Syscall.waitpid (this.pid, out Int32 status, (Native.WaitOptions) 0);
} while (UnixMarshal.ShouldRetrySyscall (r)); } while (UnixMarshal.ShouldRetrySyscall (r));
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }

View File

@ -28,6 +28,7 @@
// //
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
@ -36,13 +37,10 @@ using Mono.Unix.Native;
namespace Mono.Unix { namespace Mono.Unix {
public class UnixSignal : WaitHandle { public class UnixSignal : WaitHandle {
private int signum; private readonly Int32 signum;
private IntPtr signal_info; private IntPtr signal_info;
static UnixSignal () static UnixSignal() => Stdlib.VersionCheck();
{
Stdlib.VersionCheck ();
}
public UnixSignal (Signum signum) public UnixSignal (Signum signum)
{ {
@ -53,101 +51,101 @@ namespace Mono.Unix {
} }
} }
public UnixSignal (Mono.Unix.Native.RealTimeSignum rtsig) public UnixSignal (RealTimeSignum rtsig)
{ {
signum = NativeConvert.FromRealTimeSignum (rtsig); this.signum = NativeConvert.FromRealTimeSignum (rtsig);
this.signal_info = install (this.signum); this.signal_info = install (this.signum);
Native.Errno err = Native.Stdlib.GetLastError (); Native.Errno err = Native.Stdlib.GetLastError ();
if (this.signal_info == IntPtr.Zero) { if (this.signal_info == IntPtr.Zero) {
if (err == Native.Errno.EADDRINUSE) if (err == Native.Errno.EADDRINUSE) {
throw new ArgumentException ("Signal registered outside of Mono.Posix", "signum"); throw new ArgumentException ("Signal registered outside of Mono.Posix", "signum");
}
throw new ArgumentException ("Unable to handle signal", "signum"); throw new ArgumentException ("Unable to handle signal", "signum");
} }
} }
public Signum Signum { public Signum Signum {
get { get {
if (IsRealTimeSignal) if (this.IsRealTimeSignal) {
throw new InvalidOperationException ("This signal is a RealTimeSignum"); throw new InvalidOperationException ("This signal is a RealTimeSignum");
return NativeConvert.ToSignum (signum); }
return NativeConvert.ToSignum (this.signum);
} }
} }
public RealTimeSignum RealTimeSignum { public RealTimeSignum RealTimeSignum {
get { get {
if (!IsRealTimeSignal) if (!this.IsRealTimeSignal) {
throw new InvalidOperationException ("This signal is not a RealTimeSignum"); throw new InvalidOperationException ("This signal is not a RealTimeSignum");
return NativeConvert.ToRealTimeSignum (signum-GetSIGRTMIN ()); }
return NativeConvert.ToRealTimeSignum (this.signum -GetSIGRTMIN ());
} }
} }
public bool IsRealTimeSignal { public Boolean IsRealTimeSignal {
get { get {
AssertValid (); this.AssertValid ();
int sigrtmin = GetSIGRTMIN (); Int32 sigrtmin = GetSIGRTMIN ();
if (sigrtmin == -1) return sigrtmin == -1 ? false : this.signum >= sigrtmin;
return false;
return signum >= sigrtmin;
} }
} }
[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Unix_UnixSignal_install", SetLastError=true)] EntryPoint="Mono_Unix_UnixSignal_install", SetLastError=true)]
private static extern IntPtr install (int signum); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static extern IntPtr install (Int32 signum);
[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Unix_UnixSignal_uninstall")] EntryPoint="Mono_Unix_UnixSignal_uninstall")]
private static extern int uninstall (IntPtr info); [SuppressMessage("Microsoft.Design", "IDE1006", Justification = "Can not change name!")]
private static extern Int32 uninstall (IntPtr info);
[UnmanagedFunctionPointer (CallingConvention.Cdecl)] [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate int Mono_Posix_RuntimeIsShuttingDown (); delegate Int32 Mono_Posix_RuntimeIsShuttingDown ();
static Mono_Posix_RuntimeIsShuttingDown ShuttingDown = RuntimeShuttingDownCallback; static Mono_Posix_RuntimeIsShuttingDown ShuttingDown = RuntimeShuttingDownCallback;
static int RuntimeShuttingDownCallback () static Int32 RuntimeShuttingDownCallback() => Environment.HasShutdownStarted ? 1 : 0;
{
return Environment.HasShutdownStarted ? 1 : 0;
}
[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Unix_UnixSignal_WaitAny")] EntryPoint="Mono_Unix_UnixSignal_WaitAny")]
private static extern int WaitAny (IntPtr[] infos, int count, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down); private static extern Int32 WaitAny (IntPtr[] infos, Int32 count, Int32 timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down);
[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Posix_SIGRTMIN")] EntryPoint="Mono_Posix_SIGRTMIN")]
internal static extern int GetSIGRTMIN (); internal static extern Int32 GetSIGRTMIN ();
[DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
EntryPoint="Mono_Posix_SIGRTMAX")] EntryPoint="Mono_Posix_SIGRTMAX")]
internal static extern int GetSIGRTMAX (); internal static extern Int32 GetSIGRTMAX ();
private void AssertValid () private void AssertValid ()
{ {
if (signal_info == IntPtr.Zero) if (this.signal_info == IntPtr.Zero) {
throw new ObjectDisposedException (GetType().FullName); throw new ObjectDisposedException (this.GetType().FullName);
}
} }
private unsafe SignalInfo* Info { private unsafe SignalInfo* Info {
get { get {
AssertValid (); this.AssertValid ();
return (SignalInfo*) signal_info; return (SignalInfo*)this.signal_info;
} }
} }
public bool IsSet { public Boolean IsSet => this.Count > 0;
get {
return Count > 0;
}
}
public unsafe bool Reset () public unsafe Boolean Reset ()
{ {
int n = Interlocked.Exchange (ref Info->count, 0); Int32 n = Interlocked.Exchange (ref this.Info->count, 0);
return n != 0; return n != 0;
} }
public unsafe int Count { public unsafe Int32 Count {
get {return Info->count;} get => this.Info->count;
set {Interlocked.Exchange (ref Info->count, value);} set => Interlocked.Exchange(ref this.Info->count, value);
} }
// signum, count, write_fd, pipecnt, and pipelock are read from a signal handler thread // signum, count, write_fd, pipecnt, and pipelock are read from a signal handler thread
@ -155,71 +153,76 @@ namespace Mono.Unix {
#pragma warning disable 649 #pragma warning disable 649
[Map] [Map]
struct SignalInfo { struct SignalInfo {
public int signum, count, read_fd, write_fd, pipecnt, pipelock, have_handler; public Int32 signum, count, read_fd, write_fd, pipecnt, pipelock, have_handler;
public IntPtr handler; // Backed-up handler to restore when signal unregistered public IntPtr handler; // Backed-up handler to restore when signal unregistered
} }
#pragma warning restore 649 #pragma warning restore 649
#region WaitHandle overrides #region WaitHandle overrides
protected unsafe override void Dispose (bool disposing) protected unsafe override void Dispose (Boolean disposing)
{ {
base.Dispose (disposing); base.Dispose (disposing);
if (signal_info == IntPtr.Zero) if (this.signal_info == IntPtr.Zero) {
return; return;
uninstall (signal_info);
signal_info = IntPtr.Zero;
} }
public override bool WaitOne () _ = uninstall(this.signal_info);
{ this.signal_info = IntPtr.Zero;
return WaitOne (-1, false);
} }
public override bool WaitOne (TimeSpan timeout, bool exitContext) public override Boolean WaitOne() => this.WaitOne(-1, false);
public override Boolean WaitOne (TimeSpan timeout, Boolean exitContext)
{ {
long ms = (long) timeout.TotalMilliseconds; Int64 ms = (Int64) timeout.TotalMilliseconds;
if (ms < -1 || ms > Int32.MaxValue) if (ms < -1 || ms > Int32.MaxValue) {
throw new ArgumentOutOfRangeException ("timeout"); throw new ArgumentOutOfRangeException ("timeout");
return WaitOne ((int) ms, exitContext);
} }
public override bool WaitOne (int millisecondsTimeout, bool exitContext) return this.WaitOne ((Int32) ms, exitContext);
}
public override Boolean WaitOne (Int32 millisecondsTimeout, Boolean exitContext)
{ {
AssertValid (); this.AssertValid ();
if (exitContext) if (exitContext) {
throw new InvalidOperationException ("exitContext is not supported"); throw new InvalidOperationException ("exitContext is not supported");
if (millisecondsTimeout == 0) }
return IsSet;
return WaitAny (new UnixSignal[]{this}, millisecondsTimeout) == 0; return millisecondsTimeout == 0 ? this.IsSet : WaitAny (new UnixSignal[]{this}, millisecondsTimeout) == 0;
} }
#endregion #endregion
public static int WaitAny (UnixSignal[] signals) public static Int32 WaitAny(UnixSignal[] signals) => WaitAny(signals, -1);
{
return WaitAny (signals, -1);
}
public static int WaitAny (UnixSignal[] signals, TimeSpan timeout) public static Int32 WaitAny (UnixSignal[] signals, TimeSpan timeout)
{ {
long ms = (long) timeout.TotalMilliseconds; Int64 ms = (Int64) timeout.TotalMilliseconds;
if (ms < -1 || ms > Int32.MaxValue) if (ms < -1 || ms > Int32.MaxValue) {
throw new ArgumentOutOfRangeException ("timeout"); throw new ArgumentOutOfRangeException ("timeout");
return WaitAny (signals, (int) ms); }
return WaitAny (signals, (Int32) ms);
} }
public static unsafe int WaitAny (UnixSignal[] signals, int millisecondsTimeout) public static unsafe Int32 WaitAny (UnixSignal[] signals, Int32 millisecondsTimeout)
{ {
if (signals == null) if (signals == null) {
throw new ArgumentNullException ("signals"); throw new ArgumentNullException ("signals");
if (millisecondsTimeout < -1) }
if (millisecondsTimeout < -1) {
throw new ArgumentOutOfRangeException ("millisecondsTimeout"); throw new ArgumentOutOfRangeException ("millisecondsTimeout");
}
IntPtr[] infos = new IntPtr [signals.Length]; IntPtr[] infos = new IntPtr [signals.Length];
for (int i = 0; i < signals.Length; ++i) { for (Int32 i = 0; i < signals.Length; ++i) {
infos [i] = signals [i].signal_info; infos [i] = signals [i].signal_info;
if (infos [i] == IntPtr.Zero) if (infos [i] == IntPtr.Zero) {
throw new InvalidOperationException ("Disposed UnixSignal"); throw new InvalidOperationException ("Disposed UnixSignal");
} }
}
return WaitAny (infos, infos.Length, millisecondsTimeout, ShuttingDown); return WaitAny (infos, infos.Length, millisecondsTimeout, ShuttingDown);
} }
} }

View File

@ -36,398 +36,425 @@ using Mono.Unix;
namespace Mono.Unix { namespace Mono.Unix {
public sealed class UnixStream : Stream, IDisposable public sealed class UnixStream : Stream, IDisposable {
{ public const Int32 InvalidFileDescriptor = -1;
public const int InvalidFileDescriptor = -1; public const Int32 StandardInputFileDescriptor = 0;
public const int StandardInputFileDescriptor = 0; public const Int32 StandardOutputFileDescriptor = 1;
public const int StandardOutputFileDescriptor = 1; public const Int32 StandardErrorFileDescriptor = 2;
public const int StandardErrorFileDescriptor = 2;
public UnixStream (int fileDescriptor) public UnixStream(Int32 fileDescriptor)
: this (fileDescriptor, true) {} : this(fileDescriptor, true) { }
public UnixStream (int fileDescriptor, bool ownsHandle) public UnixStream(Int32 fileDescriptor, Boolean ownsHandle) {
{ if(InvalidFileDescriptor == fileDescriptor) {
if (InvalidFileDescriptor == fileDescriptor) throw new ArgumentException(Locale.GetText("Invalid file descriptor"), "fileDescriptor");
throw new ArgumentException (Locale.GetText ("Invalid file descriptor"), "fileDescriptor"); }
this.fileDescriptor = fileDescriptor; this.fileDescriptor = fileDescriptor;
this.owner = ownsHandle; this.owner = ownsHandle;
long offset = Native.Syscall.lseek (fileDescriptor, 0, Native.SeekFlags.SEEK_CUR); Int64 offset = Native.Syscall.lseek(fileDescriptor, 0, Native.SeekFlags.SEEK_CUR);
if (offset != -1) if(offset != -1) {
canSeek = true; this.canSeek = true;
long read = Native.Syscall.read (fileDescriptor, IntPtr.Zero, 0);
if (read != -1)
canRead = true;
long write = Native.Syscall.write (fileDescriptor, IntPtr.Zero, 0);
if (write != -1)
canWrite = true;
} }
private void AssertNotDisposed () Int64 read = Native.Syscall.read(fileDescriptor, IntPtr.Zero, 0);
{ if(read != -1) {
if (fileDescriptor == InvalidFileDescriptor) this.canRead = true;
throw new ObjectDisposedException ("Invalid File Descriptor");
} }
public int Handle { Int64 write = Native.Syscall.write(fileDescriptor, IntPtr.Zero, 0);
get {return fileDescriptor;} if(write != -1) {
this.canWrite = true;
}
} }
public override bool CanRead { private void AssertNotDisposed() {
get {return canRead;} if(this.fileDescriptor == InvalidFileDescriptor) {
throw new ObjectDisposedException("Invalid File Descriptor");
}
} }
public override bool CanSeek { public Int32 Handle => this.fileDescriptor;
get {return canSeek;}
}
public override bool CanWrite { public override Boolean CanRead => this.canRead;
get {return canWrite;}
}
public override long Length { public override Boolean CanSeek => this.canSeek;
public override Boolean CanWrite => this.canWrite;
public override Int64 Length {
get { get {
AssertNotDisposed (); this.AssertNotDisposed();
if (!CanSeek) if(!this.CanSeek) {
throw new NotSupportedException ("File descriptor doesn't support seeking"); throw new NotSupportedException("File descriptor doesn't support seeking");
RefreshStat (); }
return stat.st_size;
this.RefreshStat();
return this.stat.st_size;
} }
} }
public override long Position { public override Int64 Position {
get { get {
AssertNotDisposed (); this.AssertNotDisposed();
if (!CanSeek) if(!this.CanSeek) {
throw new NotSupportedException ("The stream does not support seeking"); throw new NotSupportedException("The stream does not support seeking");
long pos = Native.Syscall.lseek (fileDescriptor, 0, Native.SeekFlags.SEEK_CUR);
if (pos == -1)
UnixMarshal.ThrowExceptionForLastError ();
return (long) pos;
}
set {
Seek (value, SeekOrigin.Begin);
}
} }
[CLSCompliant (false)] Int64 pos = Native.Syscall.lseek(this.fileDescriptor, 0, Native.SeekFlags.SEEK_CUR);
if(pos == -1) {
UnixMarshal.ThrowExceptionForLastError();
}
return (Int64)pos;
}
set => _ = this.Seek(value, SeekOrigin.Begin);
}
//[CLSCompliant(false)]
public Native.FilePermissions Protection { public Native.FilePermissions Protection {
get { get {
RefreshStat (); this.RefreshStat();
return stat.st_mode; return this.stat.st_mode;
} }
set { set {
// we can't change file type with fchmod, so clear out that portion // we can't change file type with fchmod, so clear out that portion
value &= ~Native.FilePermissions.S_IFMT; value &= ~Native.FilePermissions.S_IFMT;
int r = Native.Syscall.fchmod (fileDescriptor, value); Int32 r = Native.Syscall.fchmod(this.fileDescriptor, value);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf(r);
} }
} }
public FileTypes FileType { public FileTypes FileType {
get { get {
int type = (int) Protection; Int32 type = (Int32)this.Protection;
return (FileTypes) (type & (int) UnixFileSystemInfo.AllFileTypes); return (FileTypes)(type & (Int32)UnixFileSystemInfo.AllFileTypes);
} }
// no set as fchmod(2) won't accept changing the file type. // no set as fchmod(2) won't accept changing the file type.
} }
public FileAccessPermissions FileAccessPermissions { public FileAccessPermissions FileAccessPermissions {
get { get {
int perms = (int) Protection; Int32 perms = (Int32)this.Protection;
return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions); return (FileAccessPermissions)(perms & (Int32)FileAccessPermissions.AllPermissions);
} }
set { set {
int perms = (int) Protection; Int32 perms = (Int32)this.Protection;
perms &= (int) ~FileAccessPermissions.AllPermissions; perms &= (Int32)~FileAccessPermissions.AllPermissions;
perms |= (int) value; perms |= (Int32)value;
Protection = (Native.FilePermissions) perms; this.Protection = (Native.FilePermissions)perms;
} }
} }
public FileSpecialAttributes FileSpecialAttributes { public FileSpecialAttributes FileSpecialAttributes {
get { get {
int attrs = (int) Protection; Int32 attrs = (Int32)this.Protection;
return (FileSpecialAttributes) (attrs & (int) UnixFileSystemInfo.AllSpecialAttributes); return (FileSpecialAttributes)(attrs & (Int32)UnixFileSystemInfo.AllSpecialAttributes);
} }
set { set {
int perms = (int) Protection; Int32 perms = (Int32)this.Protection;
perms &= (int) ~UnixFileSystemInfo.AllSpecialAttributes; perms &= (Int32)~UnixFileSystemInfo.AllSpecialAttributes;
perms |= (int) value; perms |= (Int32)value;
Protection = (Native.FilePermissions) perms; this.Protection = (Native.FilePermissions)perms;
} }
} }
public UnixUserInfo OwnerUser { public UnixUserInfo OwnerUser {
get {RefreshStat (); return new UnixUserInfo (stat.st_uid);} get {
this.RefreshStat();
return new UnixUserInfo(this.stat.st_uid);
}
} }
public long OwnerUserId { public Int64 OwnerUserId {
get {RefreshStat (); return stat.st_uid;} get {
this.RefreshStat();
return this.stat.st_uid;
}
} }
public UnixGroupInfo OwnerGroup { public UnixGroupInfo OwnerGroup {
get {RefreshStat (); return new UnixGroupInfo (stat.st_gid);} get {
this.RefreshStat();
return new UnixGroupInfo(this.stat.st_gid);
}
} }
public long OwnerGroupId { public Int64 OwnerGroupId {
get {RefreshStat (); return stat.st_gid;} get {
this.RefreshStat();
return this.stat.st_gid;
}
} }
private void RefreshStat () private void RefreshStat() {
{ this.AssertNotDisposed();
AssertNotDisposed (); Int32 r = Native.Syscall.fstat(this.fileDescriptor, out this.stat);
int r = Native.Syscall.fstat (fileDescriptor, out stat); UnixMarshal.ThrowExceptionForLastErrorIf(r);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public void AdviseFileAccessPattern (FileAccessPattern pattern, long offset, long len) public void AdviseFileAccessPattern(FileAccessPattern pattern, Int64 offset, Int64 len) => FileHandleOperations.AdviseFileAccessPattern(this.fileDescriptor, pattern, offset, len);
{
FileHandleOperations.AdviseFileAccessPattern (fileDescriptor, pattern, offset, len); public void AdviseFileAccessPattern(FileAccessPattern pattern) => this.AdviseFileAccessPattern(pattern, 0, 0);
public override void Flush() {
} }
public void AdviseFileAccessPattern (FileAccessPattern pattern) public override unsafe Int32 Read([In, Out] Byte[] buffer, Int32 offset, Int32 count) {
{ this.AssertNotDisposed();
AdviseFileAccessPattern (pattern, 0, 0); this.AssertValidBuffer(buffer, offset, count);
if(!this.CanRead) {
throw new NotSupportedException("Stream does not support reading");
} }
public override void Flush () if(buffer.Length == 0) {
{
}
public override unsafe int Read ([In, Out] byte[] buffer, int offset, int count)
{
AssertNotDisposed ();
AssertValidBuffer (buffer, offset, count);
if (!CanRead)
throw new NotSupportedException ("Stream does not support reading");
if (buffer.Length == 0)
return 0; return 0;
}
long r = 0; Int64 r = 0;
fixed (byte* buf = &buffer[offset]) { fixed(Byte* buf = &buffer[offset]) {
do { do {
r = Native.Syscall.read (fileDescriptor, buf, (ulong) count); r = Native.Syscall.read(this.fileDescriptor, buf, (UInt64)count);
} while (UnixMarshal.ShouldRetrySyscall ((int) r)); } while(UnixMarshal.ShouldRetrySyscall((Int32)r));
} }
if (r == -1) if(r == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError();
return (int) r;
} }
private void AssertValidBuffer (byte[] buffer, int offset, int count) return (Int32)r;
{
if (buffer == null)
throw new ArgumentNullException ("buffer");
if (offset < 0)
throw new ArgumentOutOfRangeException ("offset", "< 0");
if (count < 0)
throw new ArgumentOutOfRangeException ("count", "< 0");
if (offset > buffer.Length)
throw new ArgumentException ("destination offset is beyond array size");
if (offset > (buffer.Length - count))
throw new ArgumentException ("would overrun buffer");
} }
public unsafe int ReadAtOffset ([In, Out] byte[] buffer, private void AssertValidBuffer(Byte[] buffer, Int32 offset, Int32 count) {
int offset, int count, long fileOffset) if(buffer == null) {
{ throw new ArgumentNullException("buffer");
AssertNotDisposed (); }
AssertValidBuffer (buffer, offset, count);
if (!CanRead)
throw new NotSupportedException ("Stream does not support reading");
if (buffer.Length == 0) if(offset < 0) {
throw new ArgumentOutOfRangeException("offset", "< 0");
}
if(count < 0) {
throw new ArgumentOutOfRangeException("count", "< 0");
}
if(offset > buffer.Length) {
throw new ArgumentException("destination offset is beyond array size");
}
if(offset > buffer.Length - count) {
throw new ArgumentException("would overrun buffer");
}
}
public unsafe Int32 ReadAtOffset([In, Out] Byte[] buffer,
Int32 offset, Int32 count, Int64 fileOffset) {
this.AssertNotDisposed();
this.AssertValidBuffer(buffer, offset, count);
if(!this.CanRead) {
throw new NotSupportedException("Stream does not support reading");
}
if(buffer.Length == 0) {
return 0; return 0;
}
long r = 0; Int64 r = 0;
fixed (byte* buf = &buffer[offset]) { fixed(Byte* buf = &buffer[offset]) {
do { do {
r = Native.Syscall.pread (fileDescriptor, buf, (ulong) count, fileOffset); r = Native.Syscall.pread(this.fileDescriptor, buf, (UInt64)count, fileOffset);
} while (UnixMarshal.ShouldRetrySyscall ((int) r)); } while(UnixMarshal.ShouldRetrySyscall((Int32)r));
} }
if (r == -1) if(r == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError();
return (int) r;
} }
public override long Seek (long offset, SeekOrigin origin) return (Int32)r;
{ }
AssertNotDisposed ();
if (!CanSeek) public override Int64 Seek(Int64 offset, SeekOrigin origin) {
throw new NotSupportedException ("The File Descriptor does not support seeking"); this.AssertNotDisposed();
if(!this.CanSeek) {
throw new NotSupportedException("The File Descriptor does not support seeking");
}
Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR; Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR;
switch (origin) { switch(origin) {
case SeekOrigin.Begin: sf = Native.SeekFlags.SEEK_SET; break; case SeekOrigin.Begin:
case SeekOrigin.Current: sf = Native.SeekFlags.SEEK_CUR; break; sf = Native.SeekFlags.SEEK_SET;
case SeekOrigin.End: sf = Native.SeekFlags.SEEK_END; break; break;
case SeekOrigin.Current:
sf = Native.SeekFlags.SEEK_CUR;
break;
case SeekOrigin.End:
sf = Native.SeekFlags.SEEK_END;
break;
} }
long pos = Native.Syscall.lseek (fileDescriptor, offset, sf); Int64 pos = Native.Syscall.lseek(this.fileDescriptor, offset, sf);
if (pos == -1) if(pos == -1) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError();
return (long) pos;
} }
public override void SetLength (long value) return (Int64)pos;
{ }
AssertNotDisposed ();
if (value < 0)
throw new ArgumentOutOfRangeException ("value", "< 0");
if (!CanSeek && !CanWrite)
throw new NotSupportedException ("You can't truncating the current file descriptor");
int r; public override void SetLength(Int64 value) {
this.AssertNotDisposed();
if(value < 0) {
throw new ArgumentOutOfRangeException("value", "< 0");
}
if(!this.CanSeek && !this.CanWrite) {
throw new NotSupportedException("You can't truncating the current file descriptor");
}
Int32 r;
do { do {
r = Native.Syscall.ftruncate (fileDescriptor, value); r = Native.Syscall.ftruncate(this.fileDescriptor, value);
} while (UnixMarshal.ShouldRetrySyscall (r)); } while(UnixMarshal.ShouldRetrySyscall(r));
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf(r);
} }
public override unsafe void Write (byte[] buffer, int offset, int count) public override unsafe void Write(Byte[] buffer, Int32 offset, Int32 count) {
{ this.AssertNotDisposed();
AssertNotDisposed (); this.AssertValidBuffer(buffer, offset, count);
AssertValidBuffer (buffer, offset, count); if(!this.CanWrite) {
if (!CanWrite) throw new NotSupportedException("File Descriptor does not support writing");
throw new NotSupportedException ("File Descriptor does not support writing"); }
if (buffer.Length == 0) if(buffer.Length == 0) {
return; return;
}
long r = 0; Int64 r = 0;
fixed (byte* buf = &buffer[offset]) { fixed(Byte* buf = &buffer[offset]) {
do { do {
r = Native.Syscall.write (fileDescriptor, buf, (ulong) count); r = Native.Syscall.write(this.fileDescriptor, buf, (UInt64)count);
} while (UnixMarshal.ShouldRetrySyscall ((int) r)); } while(UnixMarshal.ShouldRetrySyscall((Int32)r));
}
if(r == -1) {
UnixMarshal.ThrowExceptionForLastError();
} }
if (r == -1)
UnixMarshal.ThrowExceptionForLastError ();
} }
public unsafe void WriteAtOffset (byte[] buffer, public unsafe void WriteAtOffset(Byte[] buffer,
int offset, int count, long fileOffset) Int32 offset, Int32 count, Int64 fileOffset) {
{ this.AssertNotDisposed();
AssertNotDisposed (); this.AssertValidBuffer(buffer, offset, count);
AssertValidBuffer (buffer, offset, count); if(!this.CanWrite) {
if (!CanWrite) throw new NotSupportedException("File Descriptor does not support writing");
throw new NotSupportedException ("File Descriptor does not support writing"); }
if (buffer.Length == 0) if(buffer.Length == 0) {
return; return;
}
long r = 0; Int64 r = 0;
fixed (byte* buf = &buffer[offset]) { fixed(Byte* buf = &buffer[offset]) {
do { do {
r = Native.Syscall.pwrite (fileDescriptor, buf, (ulong) count, fileOffset); r = Native.Syscall.pwrite(this.fileDescriptor, buf, (UInt64)count, fileOffset);
} while (UnixMarshal.ShouldRetrySyscall ((int) r)); } while(UnixMarshal.ShouldRetrySyscall((Int32)r));
}
if(r == -1) {
UnixMarshal.ThrowExceptionForLastError();
} }
if (r == -1)
UnixMarshal.ThrowExceptionForLastError ();
} }
public void SendTo (UnixStream output) public void SendTo(UnixStream output) => this.SendTo(output, (UInt64)output.Length);
{
SendTo (output, (ulong) output.Length); //[CLSCompliant(false)]
public void SendTo(UnixStream output, UInt64 count) => this.SendTo(output.Handle, count);
//[CLSCompliant(false)]
public void SendTo(Int32 out_fd, UInt64 count) {
if(!this.CanWrite) {
throw new NotSupportedException("Unable to write to the current file descriptor");
} }
[CLSCompliant (false)] Int64 offset = this.Position;
public void SendTo (UnixStream output, ulong count) Int64 r = Native.Syscall.sendfile(out_fd, this.fileDescriptor, ref offset, count);
{ if(r == -1) {
SendTo (output.Handle, count); UnixMarshal.ThrowExceptionForLastError();
}
} }
[CLSCompliant (false)] public void SetOwner(Int64 user, Int64 group) {
public void SendTo (int out_fd, ulong count) this.AssertNotDisposed();
{
if (!CanWrite) Int32 r = Native.Syscall.fchown(this.fileDescriptor,
throw new NotSupportedException ("Unable to write to the current file descriptor"); Convert.ToUInt32(user), Convert.ToUInt32(group));
long offset = Position; UnixMarshal.ThrowExceptionForLastErrorIf(r);
long r = Native.Syscall.sendfile (out_fd, fileDescriptor, ref offset, count);
if (r == -1)
UnixMarshal.ThrowExceptionForLastError ();
} }
public void SetOwner (long user, long group) public void SetOwner(String user, String group) {
{ this.AssertNotDisposed();
AssertNotDisposed ();
int r = Native.Syscall.fchown (fileDescriptor, Int64 uid = new UnixUserInfo(user).UserId;
Convert.ToUInt32 (user), Convert.ToUInt32 (group)); Int64 gid = new UnixGroupInfo(group).GroupId;
UnixMarshal.ThrowExceptionForLastErrorIf (r); this.SetOwner(uid, gid);
} }
public void SetOwner (string user, string group) public void SetOwner(String user) {
{ this.AssertNotDisposed();
AssertNotDisposed ();
long uid = new UnixUserInfo (user).UserId; Native.Passwd pw = Native.Syscall.getpwnam(user);
long gid = new UnixGroupInfo (group).GroupId; if(pw == null) {
SetOwner (uid, gid); throw new ArgumentException(Locale.GetText("invalid username"), "user");
} }
public void SetOwner (string user) Int64 uid = pw.pw_uid;
{ Int64 gid = pw.pw_gid;
AssertNotDisposed (); this.SetOwner(uid, gid);
}
Native.Passwd pw = Native.Syscall.getpwnam (user);
if (pw == null) //[CLSCompliant(false)]
throw new ArgumentException (Locale.GetText ("invalid username"), "user"); public Int64 GetConfigurationValue(Native.PathconfName name) {
long uid = pw.pw_uid; this.AssertNotDisposed();
long gid = pw.pw_gid; Int64 r = Native.Syscall.fpathconf(this.fileDescriptor, name);
SetOwner (uid, gid); if(r == -1 && Native.Syscall.GetLastError() != (Native.Errno)0) {
UnixMarshal.ThrowExceptionForLastError();
} }
[CLSCompliant (false)]
public long GetConfigurationValue (Native.PathconfName name)
{
AssertNotDisposed ();
long r = Native.Syscall.fpathconf (fileDescriptor, name);
if (r == -1 && Native.Syscall.GetLastError() != (Native.Errno) 0)
UnixMarshal.ThrowExceptionForLastError ();
return r; return r;
} }
~UnixStream () ~UnixStream() {
{ this.Close();
Close ();
} }
public override void Close () public override void Close() {
{ if(this.fileDescriptor == InvalidFileDescriptor) {
if (fileDescriptor == InvalidFileDescriptor)
return; return;
}
Flush (); this.Flush();
if (!owner) if(!this.owner) {
return; return;
}
int r; Int32 r;
do { do {
r = Native.Syscall.close (fileDescriptor); r = Native.Syscall.close(this.fileDescriptor);
} while (UnixMarshal.ShouldRetrySyscall (r)); } while(UnixMarshal.ShouldRetrySyscall(r));
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf(r);
fileDescriptor = InvalidFileDescriptor; this.fileDescriptor = InvalidFileDescriptor;
GC.SuppressFinalize (this); GC.SuppressFinalize(this);
} }
void IDisposable.Dispose () void IDisposable.Dispose() {
{ if(this.fileDescriptor != InvalidFileDescriptor && this.owner) {
if (fileDescriptor != InvalidFileDescriptor && owner) { this.Close();
Close ();
} }
GC.SuppressFinalize (this); GC.SuppressFinalize(this);
} }
private bool canSeek = false; private Boolean canSeek = false;
private bool canRead = false; private Boolean canRead = false;
private bool canWrite = false; private Boolean canWrite = false;
private bool owner = true; private Boolean owner = true;
private int fileDescriptor = InvalidFileDescriptor; private Int32 fileDescriptor = InvalidFileDescriptor;
private Native.Stat stat; private Native.Stat stat;
} }
} }

View File

@ -27,81 +27,60 @@
// //
using System; using System;
using System.IO;
using System.Text;
using Mono.Unix;
namespace Mono.Unix { namespace Mono.Unix {
public sealed class UnixSymbolicLinkInfo : UnixFileSystemInfo public sealed class UnixSymbolicLinkInfo : UnixFileSystemInfo
{ {
public UnixSymbolicLinkInfo (string path) public UnixSymbolicLinkInfo (String path)
: base (path) : base (path)
{ {
} }
internal UnixSymbolicLinkInfo (string path, Native.Stat stat) internal UnixSymbolicLinkInfo (String path, Native.Stat stat)
: base (path, stat) : base (path, stat)
{ {
} }
public override string Name { public override String Name => UnixPath.GetFileName(this.FullPath);
get {return UnixPath.GetFileName (FullPath);}
}
[Obsolete ("Use GetContents()")] [Obsolete("Use GetContents()")]
public UnixFileSystemInfo Contents { public UnixFileSystemInfo Contents => this.GetContents();
get {return GetContents ();}
}
public string ContentsPath { public String ContentsPath => UnixPath.ReadLink(this.FullPath);
get {
return UnixPath.ReadLink (FullPath);
}
}
public bool HasContents { public Boolean HasContents => UnixPath.TryReadLink(this.FullPath) != null;
get {
return UnixPath.TryReadLink (FullPath) != null;
}
}
public UnixFileSystemInfo GetContents () public UnixFileSystemInfo GetContents() => UnixFileSystemInfo.GetFileSystemEntry(
UnixPath.Combine(UnixPath.GetDirectoryName(this.FullPath),
this.ContentsPath));
public void CreateSymbolicLinkTo (String path)
{ {
return UnixFileSystemInfo.GetFileSystemEntry ( Int32 r = Native.Syscall.symlink (path, this.FullName);
UnixPath.Combine (UnixPath.GetDirectoryName (FullPath),
ContentsPath));
}
public void CreateSymbolicLinkTo (string path)
{
int r = Native.Syscall.symlink (path, FullName);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public void CreateSymbolicLinkTo (UnixFileSystemInfo path) public void CreateSymbolicLinkTo (UnixFileSystemInfo path)
{ {
int r = Native.Syscall.symlink (path.FullName, FullName); Int32 r = Native.Syscall.symlink (path.FullName, this.FullName);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
public override void Delete () public override void Delete ()
{ {
int r = Native.Syscall.unlink (FullPath); Int32 r = Native.Syscall.unlink (this.FullPath);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
base.Refresh (); this.Refresh();
} }
public override void SetOwner (long owner, long group) public override void SetOwner (Int64 owner, Int64 group)
{ {
int r = Native.Syscall.lchown (FullPath, Convert.ToUInt32 (owner), Convert.ToUInt32 (group)); Int32 r = Native.Syscall.lchown (this.FullPath, Convert.ToUInt32 (owner), Convert.ToUInt32 (group));
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
} }
protected override bool GetFileStatus (string path, out Native.Stat stat) protected override Boolean GetFileStatus(String path, out Native.Stat stat) => Native.Syscall.lstat(path, out stat) == 0;
{
return Native.Syscall.lstat (path, out stat) == 0;
}
} }
} }

View File

@ -29,143 +29,96 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Text; using System.Text;
using Mono.Unix;
namespace Mono.Unix { namespace Mono.Unix {
public sealed class UnixUserInfo public sealed class UnixUserInfo
{ {
private Native.Passwd passwd; private readonly Native.Passwd passwd;
public UnixUserInfo (string user) public UnixUserInfo (String user)
{ {
passwd = new Native.Passwd (); this.passwd = new Native.Passwd ();
Native.Passwd pw; Int32 r = Native.Syscall.getpwnam_r(user, this.passwd, out Native.Passwd pw);
int r = Native.Syscall.getpwnam_r (user, passwd, out pw); if (r != 0 || pw == null) {
if (r != 0 || pw == null)
throw new ArgumentException (Locale.GetText ("invalid username"), "user"); throw new ArgumentException (Locale.GetText ("invalid username"), "user");
} }
}
[CLSCompliant (false)] //[CLSCompliant (false)]
public UnixUserInfo (uint user) public UnixUserInfo (UInt32 user)
{ {
passwd = new Native.Passwd (); this.passwd = new Native.Passwd ();
Native.Passwd pw; Int32 r = Native.Syscall.getpwuid_r(user, this.passwd, out Native.Passwd pw);
int r = Native.Syscall.getpwuid_r (user, passwd, out pw); if (r != 0 || pw == null) {
if (r != 0 || pw == null)
throw new ArgumentException (Locale.GetText ("invalid user id"), "user"); throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
} }
}
public UnixUserInfo (long user) public UnixUserInfo (Int64 user)
{ {
passwd = new Native.Passwd (); this.passwd = new Native.Passwd ();
Native.Passwd pw; Int32 r = Native.Syscall.getpwuid_r(Convert.ToUInt32(user), this.passwd, out Native.Passwd pw);
int r = Native.Syscall.getpwuid_r (Convert.ToUInt32 (user), passwd, out pw); if (r != 0 || pw == null) {
if (r != 0 || pw == null)
throw new ArgumentException (Locale.GetText ("invalid user id"), "user"); throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
} }
public UnixUserInfo (Native.Passwd passwd)
{
this.passwd = CopyPasswd (passwd);
} }
private static Native.Passwd CopyPasswd (Native.Passwd pw) public UnixUserInfo(Native.Passwd passwd) => this.passwd = CopyPasswd(passwd);
{
Native.Passwd p = new Native.Passwd ();
p.pw_name = pw.pw_name; private static Native.Passwd CopyPasswd(Native.Passwd pw) => new Native.Passwd {
p.pw_passwd = pw.pw_passwd; pw_name = pw.pw_name,
p.pw_uid = pw.pw_uid; pw_passwd = pw.pw_passwd,
p.pw_gid = pw.pw_gid; pw_uid = pw.pw_uid,
p.pw_gecos = pw.pw_gecos; pw_gid = pw.pw_gid,
p.pw_dir = pw.pw_dir; pw_gecos = pw.pw_gecos,
p.pw_shell = pw.pw_shell; pw_dir = pw.pw_dir,
pw_shell = pw.pw_shell
};
return p; public String UserName => this.passwd.pw_name;
}
public string UserName { public String Password => this.passwd.pw_passwd;
get {return passwd.pw_name;}
}
public string Password { public Int64 UserId => this.passwd.pw_uid;
get {return passwd.pw_passwd;}
}
public long UserId { public UnixGroupInfo Group => new UnixGroupInfo(this.passwd.pw_gid);
get {return passwd.pw_uid;}
}
public UnixGroupInfo Group { public Int64 GroupId => this.passwd.pw_gid;
get {return new UnixGroupInfo (passwd.pw_gid);}
}
public long GroupId { public String GroupName => this.Group.GroupName;
get {return passwd.pw_gid;}
}
public string GroupName { public String RealName => this.passwd.pw_gecos;
get {return Group.GroupName;}
}
public string RealName { public String HomeDirectory => this.passwd.pw_dir;
get {return passwd.pw_gecos;}
}
public string HomeDirectory { public String ShellProgram => this.passwd.pw_shell;
get {return passwd.pw_dir;}
}
public string ShellProgram { public override Int32 GetHashCode() => this.passwd.GetHashCode();
get {return passwd.pw_shell;}
}
public override int GetHashCode () public override Boolean Equals(Object obj) => obj == null || this.GetType() != obj.GetType() ? false : this.passwd.Equals(((UnixUserInfo)obj).passwd);
{
return passwd.GetHashCode ();
}
public override bool Equals (object obj) public override String ToString() => this.passwd.ToString();
{
if (obj == null || GetType () != obj.GetType())
return false;
return passwd.Equals (((UnixUserInfo) obj).passwd);
}
public override string ToString () public static UnixUserInfo GetRealUser() => new UnixUserInfo(GetRealUserId());
{
return passwd.ToString ();
}
public static UnixUserInfo GetRealUser () public static Int64 GetRealUserId() => Native.Syscall.getuid();
{
return new UnixUserInfo (GetRealUserId ());
}
public static long GetRealUserId ()
{
return Native.Syscall.getuid ();
}
// I would hope that this is the same as GetCurrentUserName, but it is a // I would hope that this is the same as GetCurrentUserName, but it is a
// different syscall, so who knows. // different syscall, so who knows.
public static string GetLoginName () public static String GetLoginName ()
{ {
StringBuilder buf = new StringBuilder (4); StringBuilder buf = new StringBuilder (4);
int r; Int32 r;
do { do {
buf.Capacity *= 2; buf.Capacity *= 2;
r = Native.Syscall.getlogin_r (buf, (ulong) buf.Capacity); r = Native.Syscall.getlogin_r (buf, (UInt64) buf.Capacity);
} while (r == (-1) && Native.Stdlib.GetLastError() == Native.Errno.ERANGE); } while (r == -1 && Native.Stdlib.GetLastError() == Native.Errno.ERANGE);
UnixMarshal.ThrowExceptionForLastErrorIf (r); UnixMarshal.ThrowExceptionForLastErrorIf (r);
return buf.ToString (); return buf.ToString ();
} }
public Native.Passwd ToPasswd () public Native.Passwd ToPasswd() => CopyPasswd(this.passwd);
{
return CopyPasswd (passwd);
}
public static UnixUserInfo[] GetLocalUsers () public static UnixUserInfo[] GetLocalUsers ()
{ {
@ -176,13 +129,16 @@ namespace Mono.Unix {
} }
try { try {
Native.Passwd p; Native.Passwd p;
while ((p = Native.Syscall.getpwent()) != null) while ((p = Native.Syscall.getpwent()) != null) {
entries.Add (new UnixUserInfo (p)); _ = entries.Add(new UnixUserInfo(p));
if (Native.Syscall.GetLastError () != (Native.Errno) 0) }
if (Native.Syscall.GetLastError () != (Native.Errno) 0) {
UnixMarshal.ThrowExceptionForLastError (); UnixMarshal.ThrowExceptionForLastError ();
} }
}
finally { finally {
Native.Syscall.endpwent (); _ = Native.Syscall.endpwent();
} }
} }
return (UnixUserInfo[]) entries.ToArray (typeof(UnixUserInfo)); return (UnixUserInfo[]) entries.ToArray (typeof(UnixUserInfo));