dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.98k stars 4.66k forks source link

Package for Accesing to raw Linux APIs #29031

Closed deinok closed 4 years ago

deinok commented 5 years ago

Hi, I feel like there is no standard way to access to the exposed system calls of linux.

I mean, a lot of projects are building their own bindings for system calls. Of course most of this projects like corefx itself hide this API.

Wouldn't be better to create a package to wrap the linux API?

stephentoub commented 5 years ago

We generally tell developers interested in this to use: https://www.nuget.org/packages/Mono.Posix.NETStandard Even though it has "Mono" in the name, it works on .NET Core.

cc: @eerhardt

deinok commented 5 years ago

Thanks @stephentoub But there are some strange thing in that package. For example it have native shared libs.

Let me ask this in a diferent way: It would make sense to create a package that just exposes the Linux API and the package just expose the direct syscalls in a .NET syntax? A lot of packages in corefx and other project like "dotnet-iot" do this in their own way

eerhardt commented 5 years ago

@deinok - by "the Linux API" I assume you mean POSIX APIs? Check out https://github.com/dotnet/corefx/issues/15289 for more information, but that was the proposal a few years ago. We decided in that issue to not have 2 sets of public POSIX APIs, and instead only have Mono.Posix.NETStandard, which will work on Mono and .NET Core.

deinok commented 5 years ago

@eerhardt In my personal case im interested in the Linux API, but yes, there could be a POSIX Package and the Linux version depends on that.

Regarding: https://github.com/dotnet/corefx/issues/15289#issuecomment-274116942

We are deeply familiar with this problem - after all, it was my team that provided the guidance to the .NET Core team on why they should not P/Invoke into libc directly for a series of APIs on the early days of the port. Work that had to be done later on, as the team discovered the very problem that we had described to them.

I think that the key is in this comment, what are those problems? Probably this could explain me why this kind of package doesn't exist inside corefx

stephentoub commented 5 years ago

what are those problems?

There are lots of differences that show up from Unix to Unix. For example, just because a symbol has a consistent name doesn't mean it has a consistent value, e.g. ENOMSG is 42 on Ubuntu, 91 on macOS, and 83 on FreeBSD, and O_CLOEXEC is 0x80000 on Ubuntu but 0x1000000 on macOS. As another example, sometimes the name exposed in documentation is actually just a macro that expands into a varied name based on platform, e.g. you wouldn't want to try to P/Invoke to stat, as on Ubuntu the actual name exported in the binary is __xstat, and on macOS there's an $INODE64 suffix. Further, trying to P/Invoke to stat would likely lead to corruption on various platforms, because the size of the struct stat type changes from kernel to kernel, bitness to bitness, etc., with extra fields on some platforms, different orderings of fields on others, etc. Or consider ICU, which we use for globalization... while a function like UChar32 u_toupper(UChar32 c) is documented as such, in the binary the actual export includes the ICU version number as part of the name, e.g. u_toupper_52. Reasons like this make it very challenging and very brittle to try to P/Invoke directly from managed to the OS library: we instead use a native shim which exposes a consistent API we can P/Invoke to and which is in turn compiled on each platform, letting the C/C++ compiler handle all such differences.

deinok commented 5 years ago

Okey, thanks @stephentoub that explaines very well the reason to not implement in corefx my proposal.