[Mono.Posix] Support OS X ENOATTR
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=19991
The original Mono.Unix.Native.Errno design used the Linux <errno.h>
constants and values...largely because it was easy.
As it turns out, this is also incomplete. The getxattr(2) defines
ENOATTR as a possible error code. On Linux, ENOATTR is an alias for
ENODATA [0]. On OS X, ENOATTR is _not_ an alias. Furthermore, since
ENOATTR is not a Linux errno value (it's an alias!),
Mono_Posix_ToErrno() couldn't check for the native ENOATTR value, so a
Syscall.GetLastError() call after a failing Syscall.getxattr() would
fail with a System.ArgumentOutOfRangeException:
$ csharp -r:Mono.Posix.dll
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> using Mono.Unix.Native;
csharp> byte[] value;
csharp> Syscall.getxattr(".", "test", out value);
-1
csharp> Syscall.GetLastError();
System.ArgumentOutOfRangeException: Current platform doesn't support this value.
Parameter name: value
93
at Mono.Unix.Native.NativeConvert.ThrowArgumentException (System.Object value) [0x00000] in <filename unknown>:0
at Mono.Unix.Native.NativeConvert.ToErrno (Int32 value) [0x00000] in <filename unknown>:0
at Mono.Unix.Native.Stdlib.GetLastError () [0x00000] in <filename unknown>:0
The fix is to add an Errno.ENOATTR field [1].
The complication is one of what enum value to use: at present, the
Errno values are based on the Linux values. In the case of ENOATTR
(and others), there is no Linux value. Meanwhile, there is the
possibility of additional Linux error values; how do we future proof
ourselves?
This isn't a perfect solution, but it should punt the problem down the
road a bit: Errno is an `int` enum, and thus has large range. To
support the OS X values, we add 1000 to the OS X error value.
/* OS X: <errno.h> */
#define ENOATTR 93 /* Attribute not found */
// C# Errno enum:
public enum Errno : int {
// ...
ENOATTR = 1093,
}
This gives us 0..1000 for POSIX+Linux error codes, 1000..2000 for OS X
specific error codes, and as new platforms require additional support
they can all start at multiples of 1000.
Hopefully no single *nix platform will add more than 1000 error codes...
[0]: http://linux.die.net/man/2/getxattr
[1]: Related part of the fix: add all the OTHER <errno.h> values that
OS X includes but weren't included in the Errno enum.