[Mono-devel-list] RFC: Mono.Posix Class Structuring

Jonathan Pryor jonpryor at vt.edu
Sun Oct 3 21:27:22 EDT 2004

This topic isn't getting much discussion, but I could really use some
thoughts about this. :-)

At the moment, Mono.Posix (original and OEE) is a low-level wrapper for
the POSIX calls.  I find this desirable, but it's also desirable to have
higher-level wrappers for the low-level functionality.  The higher level
wrappers can throw exceptions on errors, follow the .NET PascalCasing
naming convention, and be much more consistent than strict adherence to
POSIX would normally allow.

For example, we have the low-level chown(2) function to change the owner
of a file:

	public int chown (string path, uid_t owner, gid_t group);

A nice wrapper would be:

	public void SetOwner (string path, string owner, string group);

Plus overloads to take 'owner' and 'group' by number.

The question, and the Request For Comments, is this: Where should
SetOwner go.  Keep in mind that this is an example, and should
reasonably extend to a higher-level wrapper for *all* POSIX

I see pretty much two major answers to this, with some variation.

(1) Provide the wrapper in the same class as the low-level function:

	public sealed class Unistd {
		public int chown (...) {...}
		public void SetOwner (...) {...}

I don't like this idea, as it merges the low-level and high-level
aspects within the same class.  It also can't be consistent --
PosixStream is a high-level wrapper which is also its own class (by
necessity, as it subclasses System.IO.Stream) -- so we'd have some
functions in their own classes and some functions with their low-level

Another mark against this idea is only for Mono.Posix-OEE: some
functions logically belong together but are in separate classes. 
Fcntl.open and Unistd.close belong together.  Overloading functions in
the same class won't bring these together, so this isn't a very good
convention to follow.

(2) Place the wrapper into another class.  For read(2), write(2),
fsync(2), etc., PosixStream is this class.  For chown(2), we could
introduce PosixFile:

	public class PosixFile {
		public void SetOwner (...) {...}

		public PosixStream Open (string path...) {...}
		// ...

This is nice and sensible, and is what I'm leaning toward.

Question: what conventions, if any, should such new classes follow?  And
how should these wrapper classes fit in with the low-level classes?

I see more possibilities here, and I'm not sure which is "best".  For
the record, I'm leaning toward (a).

(a) Into a new class whose name is prefixed with "Posix".  New classes
are in the Mono.Posix namespace.  Examples: Mono.Posix.PosixStream,
Mono.Posix.PosixFile, etc.

	+ you know what the higher-level classes are (they begin with
	  "Posix"), and thus which classes follow standard .NET
	+ Fewer name clashes, so "using Mono.Posix" won't cause
	  name collisions with System.IO.

	- Long class names

(b) Into a new namespace.  Mono.Posix would hold the low-level wrappers,
while (e.g.) Mono.Posix.Managed would hold the nice wrappers.  We can
then use short names in the new namespace.  For example,
Mono.Posix.Managed.Stream, Mono.Posix.Managed.File, etc.

	+ If you use "using Mono.Posix.Managed", you won't need to worry
	  about low-level wrappers showing up in Intelli-sense. :-)
	+ use shorter class names?
	- Shorter class names cause name collisions when you use obvious
	  names, so "using Mono.Posix.Managed" and "using System.IO" 
	  will cause problems.

(c) Put .NET Wrappers into Mono.Posix, and the low-level wrappers into
Mono.Posix.Native (or something else).  Otherwise, see (b).

Same Pro's and Con's as (b), effectively.  We're just moving things

Another con is that we can't provide backward-compatibility with this
approach -- Mono.Posix.Syscall would have to move (it's low-level), so
this would be a portability problem with existing code.

(c) probably isn't a good idea.

(d) (b), but with the class name convention of (a).  This results in
Mono.Posix.Managed.PosixStream, Mono.Posix.Managed.PosixFile, etc.

Same Pro's and Con's as (a), with the added (b) feature that you won't
use low-level classes by mistake.

(e) Anything else?

Feedback would be appreciated.  A wrapper isn't any good if it's isn't
useful for developers. :-)

 - Jon

More information about the Mono-devel-list mailing list