I need some simple file operations on a Linux machine, for a service installer. The code is .NET 5.0.
My current version uses Process.Start()
to execute shell commands to change the owner of files and directories and set permissions.
This is quite slow (I use asynchronous methods), especially compared to Windows equivalents.
I see libc
accessible to call from .NET has methods chmod
and chown
, however it wants uid
and gid
parameters. My application doesn't know the ids, at least without using shell for it.
So far I got something like this:
const string LIBC = "libc";
[DllImport(LIBC, SetLastError = true)]
private static extern int chmod(string path, uint mode);
[DllImport(LIBC, SetLastError = true)]
private static extern int chown(string path, int owner, int group);
So... how to get those 2 ints required?
UPDATE
Why anyone see this question (especially considering its title) as duplicate of question about similar, yet different things.
I know how to change owner and permissions of Linux files in many ways. The easiest way is to use Linux shell. The quickest and easiest way is to use Mono.Posix.NETStandard
library, that call libc
internally.
My specific question is HOW IT IS MADE? HOW DOES IT WORK?
To be even more specific:
Here's the Linux manual page for getpwnam()
:
https://man7.org/linux/man-pages/man3/getpwnam.3.html
How to just call it from C# using p/invoke? I see in many examples, that when they replace char*
with string
it somehow magically works. I created a struct like this:
public struct PASSWD {
public string pw_name; /* username */
public string pw_passwd; /* user password */
public int pw_uid; /* user ID */
public int pw_gid; /* group ID */
public string pw_gecos; /* user information */
public string pw_dir; /* home directory */
public string pw_shell; /* shell program */
};
...and tried to use it as out
parameter for the signature.
I get no error, but it just doesn't work. The struct I get is empty.
So again, we are using Platform Invoke, in C#, we are calling libc
and we want to get results from a structure. As far as I googled - it's not google-able. There is only Mono
source code, that uses external module that implements what I need. I suspect they made it for performance reasons, also - using some special tools, because in comments stands that the code is generated.
My question is again, how, using Linux manual page definition create appropriate method signature for C# to be able to extract those 2 integers from getpwnam()
.
I also was curious if something like that might already exist in .NET itself, but I guess it doesn't.