[Mono-dev] Announce: Mono.Fuse (+ Required Mono.Posix Changes)

Jonathan Pryor jonpryor at vt.edu
Tue Aug 29 08:27:02 EDT 2006

Mono.Fuse is a binding for the FUSE library, permitting user-space 
file systems to be written in C#.


I read Robert Love's announcement of beaglefs, a FUSE program that 
exposes Beagle searches as a filesystem.  My first thought: Why 
wasn't that done in C# (considering that the rest of Beagle is C#)?

What about SULF?

Stackable User-Level Filesystem, or SULF 
(http://arg0.net/users/vgough/sulf/), is a pre-existing FUSE binding 
in C#, started by Valient Gough in 2004.

Mono.Fuse has no relation to SULF, for two reasons:

  1.  It goes to great efforts to avoid a Mono.Posix.dll dependency,
      duplicating Mono.Unix.Native.Stat (Fuse.Stat),
      Mono.Unix.Native.Statvfs (Fuse.StatFS), and many methods from
      Mono.Unix.Native.Syscall (Fuse.Wrapper).

  2.  I don't like the SULF API.  (Not that I spent a great deal of
      time looking at it, but what I did see I didn't like.)

  3.  SULF wraps the FUSE kernel-level interface, while Mono.Fuse
      wraps the higher level libfuse C interface

I find (1) the most appalling, if only because I'm the Mono.Posix
maintainer and I'd like to see my work actually used. :-)

Once I started writing Mono.Fuse, I discovered a good reason to avoid
Mono.Posix: it's currently impossible to use from outside of Mono.
I figured this would be a good opportunity to rectify that, making it
easier for additional libraries to build upon the Mono.Posix


Mono.Fuse requires patches to the mcs & mono modules, changes which
need to be proposed (hence this email) and discussed.


The biggest problem with the mono module is that no headers are
installed, making it difficult to make use of libMonoPosixHelper.so.

  - Modify `configure' to generate a mono-config.h file, installed as
    $libdir/mono/include/mono-config.h.  (Basic idea "borrowed" from
    GLib's $libdir/glib-2.0/include/glibconfig.h).
  - Add a mono-posix-helper.pc file
  - Install the files $includedir/mono/posix/helper.h and

map.h is the current map.h file generated by make-map.exe, with some
major additions (detailed in the mcs section).

helper.h is the main include file, which includes map.h and declares
all types/functions which cannot be generated by make-map.exe.

mono-config.h is necessary because it needs to contain
platform-specific macros.  In particular, Linux needs:

  Mono_Posix_ToStat (struct statvfs *to, struct Mono_Posix_Helper *to);

while OS X and *BSD need:

  Mono_Posix_ToStat (struct statfs *to, struct Mono_Posix_Helper *to);

Note `struct statvfs' vs. `struct statfs'.  The mono/posix/helper.h
header needs to "paper over" the difference, and thus needs to know
which type the platform prefers.  helper.h thus looks like:

    struct statvfs;
    int Mono_Posix_ToStatvfs (struct statvfs *from, 
        struct Mono_Posix_Statvfs *to);
    struct statfs;
    int Mono_Posix_ToStatvfs (struct statfs *from, 
        struct Mono_Posix_Statvfs *to);

One of MONO_HAVE_STATVFS or MONO_HAVE_STATFS would be defined in


There are two major changes:

  * The addition of one public attributes to the API:

    // targets Class, Delegate, Enum, Field, Struct
    class Mono.Unix.Native.MapAttribute {
      public MapAttribute ();
      public MapAttribute (string nativeType);
      public string NativeType {get;}
      public string NativeSymbolPrefix {get; set;}

  * A major revamp to make-map.exe

The Map and MapHeader attributes are public so that make-map.exe can
use a publically exposed API for code generation purposes which can be
used by other libraries (Mono.Fuse makes use of these changes).

Make-map.exe can also generate structure declarations and delegate
declarations in addition to P/Invoke function declarations,
allowing for a better, automated interface between C and C#.

Previously, [Map] could only be used on enumerations.

Now, [Map] can be used on classes, structures, & delegates, to create
a C declaration of the C# type, suitable for P/Invoke purposes, e.g.

  [Map] struct Stat {public FilePermissions mode;}

would generate the C declaration

  struct Namespace_Stat {unsigned int mode;};

The MapAttribute.NativeType property is used to specify that type
conversion functions should be generated, thus:

  [Map ("struct stat")] struct Stat {public FilePermissions mode;}

would generate

  struct Namespace_Stat {unsigned int mode;};
  int Namespace_ToStat (struct stat *from, struct Namespace_Stat *to);
  int Namespace_FromStat (struct Namespace_Stat *from, struct stat *to);

along with the actual implementations of Namespace_ToStat() and

The MapAttribute.NativeSymbolPrefix is used to specify the C
"namespace" to use:

  [Map (NativeSymbolPrefix="Foo")] struct Stat {FilePermissiond mode;}


  struct Foo_Stat {unsigned int mode;};

This prefix is also used for the conversion functions.

(You may be wondering why NativeSymbolPrefix exists at all.  This is
for reasonable symbol versioning -- make-map.exe currently has a
"hack" in place to rename Mono.Unix(.Native) to Mono_Posix, a hack
I'd like to remove, and NativeSymbolPrefix allows the Mono.Unix.Native
types to have a "Mono_Posix" C namespace in a reasonably general 

The previously internal Mono.Unix.HeaderAttribute has been removed.
The HeaderAttribute.Includes and HeaderAttribute.Defines properties
have been replaced with make-map.exe command-line arguments.  In
particular, HeaderAttribute.Includes has been replaced with
--autoconf-header, --impl-header, --impl-macro, --public-header, and
--public-macro (the first three modify the generated .c file, while
the latter two modify the generated .h file).

Finally, make-map.exe has been renamed and moved from
mcs/class/Mono.Posix/Mono.Unix.Native/make-map.exe to


Go to http://www.jprl.com/mono-fuse for the patches and source download.

Apply ``mcs.patch'' to a ``mcs'' checkout, rebuild, and install.
Apply ``mono.patch'' to a ``mono'' checkout, rebuild, and install.
Build ``mono-fuse-0.1.0.tar.gz'' in "the standard manner" (ye olde
"./configure; make; make install" business).


  - Is it OK for create-native-map.exe to be a .NET 2.0 app?

  - How should we cope with unstable APIs which make use of native 
    code?  The Application Deployment Guidelines [1] don't address
    this issue, nor the related issue of what should be done with
    64-bit binaries.  In particular, for an AMD64 machine, which
    directory layout should be used for an assembly + native lib
    1. What Mono seems to do, with the GAC in $prefix/lib no matter
       what the architecture:

    2. Be consistent, and toss everything in @libdir@:



 - Jon

More information about the Mono-devel-list mailing list