First version

This commit is contained in:
alhimik45
2018-01-05 01:24:49 +07:00
commit 86ebf4962a
19 changed files with 6695 additions and 0 deletions

291
.gitignore vendored Normal file
View File

@@ -0,0 +1,291 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
buildlibs/*
nativelibs/linux-x64/*

743
ChangeLog Normal file
View File

@@ -0,0 +1,743 @@
2016-06-08 Justin Needham <jneedhamspkt@gmail.com>
Migrate from gmcs to mcs for Mono 4.*
* configure.ac: gmcs --> mcs
* doc/en/Mono.Fuse/FileSystem.xml : gmcs --> mcs
2008-04-01 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Error if `mono' can't be found (not continue), and continue
if `monodoc' can't be found (not error). Simplify.
2008-01-30 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Bump version numbers; genreate mono-fuse.spec.
* Makefile.am: Add `rpm', `prepare-release' targets.
* example/HelloFS/Makefile.am, example/RedirectFS/Makefile.am,
lib/mono-fuse/Makefile.am, src/Mono.Fuse/Makefile.am,
src/MonoFuseHelper/Makefile.am: Enhance so `make distcheck works`.
* .gitignore, doc/.gitignore, example/HelloFS/.gitignore,
example/RedirectFS/.gitignore, lib/.gitignore, lib/mono-fuse/.gitignore,
lib/pkgconfig/.gitignore, src/Mono.Fuse/.gitignore,
src/MonoFuseHelper/.gitignore: Added; ignore generated files.
* INSTALL: Added; install information.
* src/Mono.Fuse/AssemblyInfo.cs.in: Added; contains assembly version info.
* mono-fuse.spec.in: Added; RPM .spec file; thanks to
Jay Miller <jnmiller@cryptofreak.org> for the original version.
2007-06-29 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: My sh-fu needs work. Properly check the return value of
`gmcs' so I can determine whether it compiled successfully.
2007-06-29 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Use a better check for the
Mono.Unix.Native.NativeConvert.TryCopy() methods, as relying on
libMonoPosixHelper.so is inadequate.
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Use NativeConvert.TryCopy(), not
NativeConvert.Copy(). (NativeConvert.Copy() was only proposed, but never
made it into an official Mono.Posix release, while .TryCopy did.)
2007-04-17 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/hellofs.in, example/RedirectFS/redirectfs.in,
example/RedirectFS/redirects-fh.in: Define DYLD_LIBRARY_PATH so that
example programs work seamlessly on OS X as well as Linux.
* lib/mono-fuse/Mono.Fuse.dll.config: Added; Mono dllmap config file so that
MonoFuseHelper is redirected to libMonoFuseHelper.dylib on Mac OS X.
* src/Mono.Fuse/Makefile.am: Install the Mono.Fuse.dll.mdb and
Mono.Fuse.dll.config files.
2007-04-17 Jonathan Pryor <jonpryor@vt.edu>
* src/MonoFuseHelper/Makefile.am: Define HAVE_STRUCT_FUSE_ARGS so that
map.c's Mono_Fuse_ToArgs() and Mono_Fuse_FromArgs() will be compiled.
Otherwise, we get an unsatisfied link error when loading MonoFuseHelper.
2007-04-17 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/create-native-map.exe, src/Mono.Fuse/MapAttribute.cs: Update
to latest versions (fixes buggy overflow checking in MonoFuseHelper).
* lib/Mono.Fuse/Makefile.am: FUSE_USE_VERSION should be in the .c file, not
the .h file. Also fixes Mac OS X compilation, as FUSE_USE_VERSION needs
to be defined *before* including <fuse.h>, but <fuse.h> is inserted before
the include of lib/map.h -- bad order.
2007-01-17 Jonathan Pryor <jonpryor@vt.edu>
* src/MonoFuseHelper/Makefile.am: Use $(LIBTOOL), not `libtool', as the
libtool program may go by different names on different platforms (e.g.
glibtool on OS X).
2006-10-31 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/HelloFS.cs: Add extra Trace statements; remove unused code.
2006-10-23 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Add [In,Out] to the
FileSystmeOperationContext parameter in mfh_fuse_get_context().
Otherwise, the data is never marshaled back into managed memory, so all
fields are zero'd out (making the method useless). Oops!
2006-10-12 Jonathan Pryor <jonpryor@vt.edu>
* doc/mono-fuse-docs.source: Update @basefile to contain the actual
basefile. Allows installed monodoc documentation to work.
2006-10-12 Jonathan Pryor <jonpryor@vt.edu>
* doc/Makefile.am: Add `-pretty' so monodocer produces nicely indented XML.
* doc/en/Mono.Fuse/DirectoryEntry.xml, doc/en/Mono.Fuse/FileSystem.xml,
doc/en/Mono.Fuse/FileSystemOperationContext.xml,
doc/en/Mono.Fuse/OpenedPathInfo.xml: Flush documentation (largest change
was due to reformatting of XML). Also used svn version of monodocer to
get proper Generics-formatted method declarations, so
FileSystem.OnReadDirectory now lists a parameter of
System.Collections.Generic.IEnumerable<Mono.Fuse.DirectoryEntry> instead
of System.Collections.Generic.IEnumerable`1[[Mono.Fuse.DirectoryEntry,
Mono.Fuse, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].
* src/Mono.Fuse/create-native-map.exe: Commit latest version; fixes #ifndef
name formatting so that SYMBOL in "#ifndef SYMBOL" doesn't contain `/'.
2006-09-21 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Remove checks for mint. Mint is dead.
2006-09-21 Jonathan Pryor <jonpryor@vt.edu>
* doc/en/Mono.Fuse/FileSystem.xml, doc/en/Mono.Fuse/OpenedPathInfo.xml:
Minor doc updates.
2006-09-20 Jonathan Pryor <jonpryor@vt.edu>
* doc/Makefile.am: Create mono-fuse-docs.* files, not mono-fuse.* files.
This matches Gtk#, and allows for clarity if we ever have
mono-fuse-docs.zip and mono-fuse-VERSION.tar.gz in the same directory.
* doc/en/index.xml, doc/en/Mono.Fuse.xml, doc/en/Mono.Fuse/DirectoryEntry.xml,
doc/en/Mono.Fuse/FileSystem.xml,
doc/en/Mono.Fuse/FileSystemOperationContext.xml,
doc/en/Mono.Fuse/OpenedPathInfo.xml: Add documentation.
* doc/en/Mono.Fuse/FileSystemEntry.xml: Renamed to DirectoryEntry.xml.
* example/HelloFS/HelloFS.cs: Use DirectoryEntry instead of FileSystemEntry;
use OpenedPathInfo.OpenAccess instead of OpenedPathInfo.OpenReadOnly.
* example/RedirectFS/RedirectFS.cs, example/RedirectFS/RedirectFS-FH.cs: Use
DirectoryEntry instead of FileSystemEntry;
s/OnCloseDirectory/OnReleaseDirectory/.
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Changes by type:
- FileSystemOperationContext:
- Make sealed (this should only be created internally).
- Constructor is now internal.
- FileSystemEntry:
- Renamed to DirectoryEntry.
- Renamed Path property to Name.
- Add argument checking to DirectoryEntry constructor.
- Remove implicit conversion to string (as constructor may generate
exceptions).
- OpenedPathInfo:
- Make seaeled (this should only be created internally).
- Constructor now internal.
- Remove OpenReadOnly, OpenWriteOnly, OpenReadWrite properties
- Add OpenAccess property.
- FileSystem:
- Now `abstract'. There are no abstract methods, but it's pointless
to create instances of this type, as it wouldn't do anything.
- Make constructors protected (to emphasize the above).
- Rename FileSystemName property to Name.
- Rename ImmediateRemoval property to ImmediatePathRemoval.
- Rename DirectIO property to EnableDirectIO.
- Rename Umask property to DefaultUmask.
- Add EnableKernelCache property.
- Rename UserId property to DefaultUserId.
- Rename GroupId property to DefaultGroupId.
- Rename EntryTimeout property to PathTimeout.
- Rename DeletedNameTimeout property to DeletedPathTimeout.
- Change types of Timeout properties to `double' from `int'; changes
PathTimeout, DeletedPathTimeout, AttributeTimeout.
- Rename OnCloseDirectory() method to OnReleaseDirectory() (for
consistency with OnReleaseHandle).
- Rename Exit() method to Stop().
- Rename parameters of many methods to match the method names -- e.g.
OnReadSymbolicLink() takes a `link' parameter instead of `path',
OnOpenDirectory() takes a `directory' parameter instead of `path', etc.
2006-09-12 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Makefile.am: Add FileNameMarshaler to the build.
* src/Mono.Fuse/Mono.Fuse/FileNameMarshaler.cs: Added; marshals filenames
with any encoding to/from managed code (from
Mono.Unix.Native.FileNameMarshaler).
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs:
- Use the FileNameMarshaler custom marshaler to manipulate filenames
entering/leaving managed code. This allows manipulation of filenames
with non-UTF8 encodings.
- Reimplement FillEntries(). When mfh_invoke_filler() returns 1, it means
that the current entry was not inserted, and needs to be inserted during
the next call. Previously, if a directory had many files (i.e.
_OnReadDirectory() was called > 2 times), it would "drop" the file that
was passed to mfh_invoke_filler() when it returned 1. Now, when
mfh_invoke_filler() return 1, we remember this and return the current
entry a 2nd time so that nothing is lost.
2006-09-11 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Fix test for HAVE_MONO_UNIX_NATIVE_COPY_FUNCS; Add check for
`mdassembler' and `monodocer' (from monodoc module); create doc/Makefile.
* Makefile.am: Add `doc' directory to the build.
* doc/Makefile.am: Added; build the Monodoc documentation.
* doc/README: Added; short overview for adding docs to monodoc.
* doc/mono-fuse.source: Added; monodoc source file (where in the tree the
Mono.Fuse sources should be placed).
* doc/en/index.xml, doc/en/Mono.Fuse.xml, doc/en/Mono.Fuse/FileSystem.xml,
doc/en/Mono.Fuse/FileSystemEntry.xml,
doc/en/Mono.Fuse/FileSystemOperationContext.xml,
doc/en/Mono.Fuse/OpenedPathInfo.xml: Added; API documentation stubs.
* src/MonoFuseHelper/Makefile.am: Remove automake warning message.
2006-09-11 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/HelloFS.cs: Add extended attribute support for the
`hello' file.
2006-09-11 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs:
- Property renaming: s/Options/FuseOptions/g.
- Method renaming:
s/OnSetPathExtendedAttributes/OnSetPathExtendedAttribute/g;
s/OnGetPathExtendedAttributes/OnGetPathExtendedAttribute/g;
- Method argument changing:
s/OnListPathExtendedAttributes(string, byte[], out int)/
OnListPathExtendedAttributes(string, out string[])/
* example/HelloFS/HelloFS.cs: s/\.Options/.FuseOptions/g.
* example/HelloFS/Makefile.am: Add `-debug+' to compile line for
HelloFS.exe; add Mono.Fuse.dll.mdb for line numbers in stack traces.
* example/RedirectFS/RedirectFS.cs, example/RedirectFS/RedirectFS-FH.cs:
Update to latest OnSetPathExtendedAttribute(),
OnGetPathExtendedAttribute(), OnListPathExtendedAttributes() methods.
2006-09-09 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse.FileSystem.cs:
- Add new public type FileSystemEntry, which provides both a Path string
and a Mono.Unix.Native.Stat instance that can be passed to FUSE. The
Stat instance will _only_ be used if Stat.st_ino is non-zero.
- Change FileSystemOperationContext to use read-only properties instead of
fields, as this information can't be changed. Change ProcessId to `int'
instead of `long', for consistency with Mono.Posix.
- Change FileSystem.OnReadDirectory() to use IEnumerable<FileSystemEntry>
instead of IEnumerable<string>. This allows sub-classes to (optionally)
provide Stat information to FUSE. (Currently FUSE will only use the
st_ino & st_mode fields of the Stat, though I imagine this may be
expanded in the future.)
* src/MonoFuseHelper/mfh.c: Use current field names in
FileSystemOperationContext.
* example/HelloFS/HelloFS.cs:
s/IEnumerable<string>/IEnumerable<FileSystemEntry>/g (migrate to latest
Mono.Fuse.FileSystem.OnReadDirectory() prototype).
* example/RedirectFS/RedirectFS.cs, example/RedirectFS/RedirectFS-FH.cs:
s/IEnumerable<string>/IEnumerable<FileSystemEntry>/g (migrate to latest
Mono.Fuse.FileSystem.OnReadDirectory() prototype); Fill in
FileSystemEntry.Stat for use by FUSE.
2006-09-08 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs:
- Redo OnReadDirectory() implementation to use a IEnumerator instead of a
string[]. The previous approach required reading in the entire
directory all at once, which would slow things down for large
directories. The new approach allows FUSE to invoke _OnReadDirectory()
multiple times to read from the same enumerator, allowing directory
entries to be returned in "chunks" instead of all at once.
Plus, it's damn cool to use a C# iterator to implement
OnReadDirectory() (see HelloFS.cs & RedirectFS-FH.cs).
- Remove check for OnCreateHandle()/OnOpenHandle() & OnReleaseHandle()
consistency -- this broke the build (HelloFS has OnOpenHandle() but not
OnReleaseHandle(), and it doesn't need OnReleaseHandle() either).
* src/MonoFuseHelper/mfh.c: Help implement new OnReadDirectory() interface;
add mfh_invoke_filler() helper method.
* example/HelloFS/HelloFS.cs, example/RedirectFS/RedirectFS.cs,
* example/RedirectFS/RedirectFS-FH.cs: Implement updated OnReadDirectory()
interface. (Using iterators for OnReadDirectory is cool; especially
check out the new RedirectFS-FH.cs implementation.)
2006-09-07 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs:
- Add initial validation for method overriding -- some methods come in
sets. For example, if OnOpenDirectory is overridden, OnCloseDirectory()
should be as well (to ensure that any handles are closed if desired).
Perform such sanity checking.
- Correct GetOperations() so that the methods it finds via Reflection
actually override the methods it thinks are being overridden.
2006-09-07 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/HelloFS.cs: Update help text to show FUSE options.
* example/RedirectFS/RedirectFS.cs, example/RedirectFS/RedirectFS-FH.cs:
Update help text to show FUSE options. Alter command line arguments to be
"program mountpoint basedir" (instead of "program basedir mountpoint") so
that it matches the FUSE-generated help text.
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Add ShowFuseHelp static method to
display FUSE help options to stderr.
* src/MonoFuseHelper/mfh.c: Add mfh_show_fuse_help() helper.
2006-09-07 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Generate Makefile for new directory example/RedirectFS.
* src/Mono.Fuse/MapAttribute.cs: Update to latest mono-tools version.
* src/Mono.Fuse/create-native-map.exe: Update to latest mono-tools version
(removes support for MapAttribute.NativeSymbolPrefix, as this is no longer
useful since MonoPosixHelper doesn't have a public API).
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs:
- Rename OpenedPathInfo.FileHandle to OpenedPathInfo.Handle (as the
handle can be used by both files & directories).
- Change ReadSymbolicLinkCb/OnReadSymbolicLink() as Mono can't pass a
StringBuilder from native to managed code (it's a managed->native
construct), so use a workable alternative. The new
``OnReadSymbolicLink(string path, out string target)'' prototype is also
simpler for subclasses.
- Native code can't pass an OpenedPathInfo into managed code via the
delegates, as the delegates need to modify OpenedPathInfo.Handle and
have this change propogate back to native code. Ideally, this would be
fixed by making the delegates have an "[In, Out] OpenedPathInfo info"
parameter (instead of the current "IntPtr" + manual marshal approach),
but this causes Mono to die -- bugzilla 79298. This is now fixed, but
only in HEAD, so we need the ugly workaround for 1.1.13.x support.
- Add support for parsing the `-f' FUSE argument (use foreground
operation; ignored, as we can only support foreground operation).
- Don't throw Exception if MountPoint can't be mounted or mfh_fuse_new
fails, throw a NotSupportedException. (Perhaps I should use a
different type?)
- Remove some Console.WriteLine()s.
* src/MonoFuseHelper/Makefile.am: $(buildlibdir)/libMonoFuseHelper.so should
be updated when its sources are updated.
* src/MonoFuseHelper/mfh.c:
- Add Mono_Fuse_FromOpenedPathInfo and Mono_Fuse_ToOpenedPathInfo (for
struct fuse_file_info conversion), so it can be invoked by Mono.Fuse.dll.
- Remove support for fuse_file_info->OpenedPathInfo conversion from
MonoFuseHelper, this must now be done in managed code (see #79298).
- mfh_readdir: Check return value of `filler' method to check for errors.
* example/Makefile.am: Add new directory RedirectFS.
* example/RedirectFS/Makefile.am: Added; build RedirectFS programs.
* example/RedirectFS/RedirectFS.cs: Added; FS which forwards ("redirects")
all FileSystem operations to the underlying filesystem.
* example/RedirectFS/redirectfs.in: Added; runs RedirectFS.exe.
Syntax: redirectfs BASEDIR MOUNT-POINT
e.g. ./redirects /tmp t
* example/RedirectFS/RedirectFS-FH.cs: Added; FS which forwards ("redirects")
all FileSystem operations to the underlying filesystem.
This uses OpenedPathInfo.Handle to track file & directory handles instead
of re-opening files & directories all the time (compare to RedirectFS.cs).
* example/RedirectFS/redirectfs-fh.in: Added; runs RedirectFS-FH.exe.
Syntax: redirectfs-fh BASEDIR MOUNT-POINT
e.g. ./redirects-fh /tmp t
2006-09-05 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Mass API renaming for consistency.
- s/OpenedFileInfo/OpenedPathInfo/g (for consistency with method naming
convention, below, as it's used with both files & directories).
- Remove FileSystemOperationContext.PrivateData (it's used internally).
- Rename properties: s/EnableDebugOutput/EnableFuseDebugOutput/.
- Add MultiThreaded property (default true), remove StartMultithreaded()
method. Start() checks the MultiThreaded property and calls the
appropriate FUSE method for (non-) multithreaded use.
- Make OpenedPathInfo parameter 2nd parameter instead of the (variable)
last parameter (so that `out' parameters can consistently be the last
parameter and paramater placement is consistent).
- Change method names for consistency, ease understanding, and help the
impending documentation effort to include one of the following words:
- Directory: Method deals with directories and not files.
- OnCreateDirectory(), OnRemoveDirectory(), OnOpenDirectory(),
OnReadDirectory(), OnCloseDirectory(), OnSynchronizeDirectory().
- File: Method deals with files and not directories.
- OnCreateSpecialFile(), OnRemoveFile(), OnTruncateFile().
- FileSystem: Method deals with the file system as a whole.
- OnGetFileSystemStatus().
- Link: Method deals with actual links (symbolic & hard links)
- OnCreateHardLink(), OnCreateSymbolicLink(), OnReadSymbolicLink().
- Handle: Method deals with a "handle" to an opened file.
- OnCreateHandle(), OnOpenHandle(), OnReadHandle(), OnWriteHandle(),
OnFlushHandle(), OnReleaseHandle(), OnSynchronizeHandle(),
OnTruncateHandle(), OnGetHandleStatus().
- Path: Method works on files and directories.
- OnAccessPath(), OnGetPathStatus(), OnRenamePath(),
OnChangePathPermissions(), OnChangePathOwner(), OnChangePathTimes(),
OnGetPathExtendedAttributes(), OnListPathExtendedAttributes(),
OnSetPathExtendedAttributes(), OnRemovePathExtendedAttribute().
* src/MonoFuseHelper/mfh.c: Deal with s/OpenedFileInfo/OpenedPathInfo/g.
* example/HelloFS/HelloFS.cs: Deal with FileSystem method name changes.
2006-09-03 Jonathan Pryor <jonpryor@vt.edu>
* COPYING: Specify license as MIT/X11.
* example/HelloFS/HelloFS.cs, src/Mono.Fuse/FileSystem.cs,
src/MonoFuseHelper/mfh.c, src/MonoFuseHelper/mph.c: Add license.
2006-09-01 Jonathan Pryor <jonpryor@vt.edu>
* README: Add note about using fusermount to unmount FUSE filesystems.
2006-09-01 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Set required Mono version is 1.1.13 (maybe could be
lowered? No idea); add check for presence of Mono_Posix_ToStat in
MonoPosixHelper -- if found, then we should have the new
Mono.Unix.Native.NativeConvert.Copy methods, otherwise we need to roll our
own equivalents. This allows portability to "down-level" mono versions.
* src/Mono.Fuse/create-native-map.exe: Update; this version doesn't skip
prototypes for structs within a different assembly, it generates struct
declarations for all structs referenced (needed to get struct decls for
Stat, Statvfs, etc.)
* src/Mono.Fuse/Makefile.am: Add --rename-member arguments to
create-native-map call so Stat can be used properly.
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Only use NativeConvert.Copy methods
if HAVE_MONO_UNIX_NATIVE_COPY_FUNCS is defined, otherwise use the
MonoFuseHelper internal methods.
* src/MonoFuseHelper/Makefile.am: Add mph.c to the build.
* src/MonoFuseHelper/mph.c: Added; structure copy functions from
MonoPosixHelper for copying Stat, Statvfs, & Utimbuf between managed &
native code.
2006-09-01 Jonathan Pryor <jonpryor@vt.edu>
* README: Add comments about hellofs command-line arguments, capturing trace
messages, and FUSE performance timing.
* example/HelloFS/hellofs.in: Modify setting of LD_LIBRARY_PATH so that it
retains the existing $LD_LIBRARY_PATH value. Remove -odebug parameter.
If you want "full" trace output, set MONO_TRACE_LISTENER for the managed
trace output, and add -odebug for FUSE trace output, e.g.
MONO_TRACE_LISTENER=Console.Out:### ./hellofs -odebug mount-point
2006-08-31 Jonathan Pryor <jonpryor@vt.edu>
* src/Mono.Fuse/Makefile.am: Remove dependency on external
create-native-map.exe and a public Mono.Unix.Native.MapAttribute (as the
latter will no longer be public). Add `update-map-source' target which
uses pkg-config to copy the "reference" MapAttribute.cs &
create-native-map.exe programs from their installed locations.
* src/Mono.Fuse/create-native-map.exe, src/Mono.Fuse/MapAttribute.cs: Added;
cached versions of create-native-map.exe & MapAttribute.cs as provided by
pkg-config and the create-native-map.pc file.
2006-08-31 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Remove use of mono-posix-helper.pc, and use glib-2.0
instead.
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Change the delegates so that they
use only native types, not managed types. Change all of the _On*
methods to do the native->managed conversion for parameters and the return
value (depends upon addition of Mono.Unix.Native.NativConvert.Copy()
methods to perform structure conversion). Make OpenedFileInfo.flags
internal, so that FileSystem can convert the value when necessary,
as MonoFuseHelper can't do the enum convert.
* src/MonoFuseHelper/Makefile.am: Remove use of MPH, and add GLIB flags.
* src/MonoFuseHelper/mfh.c: Remove use of MonoPosixHelper functions (as
Mono.Fuse.FileSystem does the type conversions now). Don't copy-out
OpenedFileInfo.flags, as this enum must be converted in managed, and I
don't see much point in having another conversion on exit when I can just
skip the copy-out (thus preserving the original value).
2006-08-31 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/HelloFS.cs: Make creation of data_im_str thread-safe, so
that it's only created once and reading threads don't see an intermediate
state.
2006-08-28 Jonathan Pryor <jonpryor@vt.edu>
* example/HelloFS/HelloFS.cs: Rename the ``data'' file to ``data.im'' (this
is a text file with 100MB of data), and replace ``data'' with a file which
computes its content at runtime (a time/space tradeoff). The ``data.im''
file isn't available by default; pass --data.im-in-memory to make it
available (note that this file will be created in-memory the first time
its content is accessed). Add command-line argument parsing. Use
Trace.WriteLine instead of Console.WriteLine.
* lib/pkgconfig/mono-fuse.pc.in: Use @libdir@ instead of
${prefix}/@reloc_libdir@. I'm not sure what @reloc_libdir@ is supposed to
be, and it isn't currently expanded anyway.
* src/Mono.Fuse/Makefile.am: Add the -d:TRACE define. Add --public-macro
and --impl-header to the create-native-map call (create-native-map no
longer supports MapHeaderAttribute).
* src/Mono.Fuse/Mono.Fuse/FileSystem.cs: Remove use of
Mono.Unix.Native.MapHeaderAttribute (use create-native-map arguments
instead). Add public argument parsing support (so that HelloFS can have
its own command-line args in addition to the FUSE args). Use Trace
instead of Console for trace messages. Add a `catch(Exception)' handler
so we can trace exception messages (helps debugging).
2006-08-25 Jonathan Pryor <jonpryor@vt.edu>
* src/MonoFuseHelper/mfh.c: Remove debug printf statements.
2006-08-24 Jonathan Pryor <jonpryor@vt.edu>
* Makefile.am: Build the `lib' directory.
* lib/mono-fuse/Makefile.am: Don't install anything;
src/Mono.Fuse/Makefile.am already handles Mono.Fuse.dll installation.
2006-08-24 Jonathan Pryor <jonpryor@vt.edu>
* configure.in: Don't forget to generate lib/mono-fuse/Makefile!
2006-08-24 Jonathan Pryor <jonpryor@vt.edu>
* lib/Makefile.am: Build the mono-fuse directory as well
* lib/mono-fuse/Makefile.am: Added; installs Mono.Fuse.dll.
2006-08-24 Jonathan Pryor <jonpryor@vt.edu>
* NEWS: Added
* configure.in: Use AM_PROG_LIBTOOL, not AC_PROG_LIBTOOL, to satisfy
autogen.sh's checking.
2006-08-24 Jonathan Pryor <jonpryor@vt.edu>
* AUTHORS, COPYING, README: Added (for autoconf)
* autogen.sh, configure.in, Makefile.am, example/Makefile.am,
example/HelloFS/Makefile.am, lib/Makefile.am, lib/pkgconfig/Makefile.am,
src/Makefile.am, src/Mono.Fuse/Makefile.am,
src/MonoFuseHelper/Makefile.am: Added (auto* build system files).
* lib/map.c, lib/map.h: Removed (generated by the build; no need to keep
these under version control).
* lib/mfh.c: Renamed to src/MonoFuseHelper/mfh.c
* lib/mph.c: Removed. (Functions added to MonoPosixHelper library.)
* lib/mono-fuse/HelloFS.cs: Renamed to example/HelloFS/HelloFS.cs
* example/HelloFS/hellofs.in: Added; template for `hellofs' program.
* lib/mono-fuse/MakeMap.Test.cs, lib/mono-fuse/make-map.cs,
lib/mono-fuse/test.c.ref, lib/mono-fuse/test.cs.ref,
lib/mono-fuse/test.h.ref, lib/mono-fuse/test.xml.ref: Removed.
make-map.exe renamed to create-native-map.exe, moved into
mcs svn module under mcs/tools/create-native-map.
* lib/pkgconfig/mono-fuse.pc.in: Remove Requires line (managed code doesn't
depend on glib-2.0 or mono), add Mono.Posix.dll to Libs: line.
* lib/mono-fuse/FileSystem.cs: renamed to
src/Mono.Fuse/Mono.Fuse/FileSystem.cs
2006-08-21 Jonathan Pryor <jonpryor@vt.edu>
* lib/map.c, lib/map.h: Flush (current make-map output for Mono.Fuse.dll).
* lib/mono-fuse/MakeMap.Test.cs: Add additional tests for copying nested
structures.
* lib/mono-fuse/make-map.cs: Add support for copying nested structures.
* lib/mono-fuse/test.c.ref, lib/mono-fuse/test.h.ref: Flush.
2006-08-21 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/MakeMap.Test.cs: Add enum (to test enum conversion code),
class w/o namespace (generated NRE within make-map).
* lib/mono-fuse/make-map.cs:
- s/ExportPrefix/NativeSymbolPrefix/g (current Mono.Posix.dll naming);
- check for t.Namespace==null before looking using
Configuration.NamespaceRenames (Dictionary`2 doesn't like null keys);
- HeaderFileGenerator needs to know about member renames (so it uses the
renamed member in conversion code);
- Clean up enumeration generation for readablility.
- Remove dependency on <mono/posix/limits.h> (include macros within file
with a _cnm prefix).
* lib/mono-fuse/test.c.ref, lib/mono-fuse/test.cs.ref,
lib/mono-fuse/test.h.ref, lib/mono-fuse/test.xml.ref: Flush.
2006-08-21 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/make-map.cs: Remove debug statements.
2006-08-21 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/Makefile: Add --library when generating ../map.c, ../map.h.
* lib/mono-fuse/make-map.cs: Use Mono.Unix.Native.MapAttribute.ExportPrefix
to get the namespace of a member, in addition to --rename-namespace. This
is necessary for easier cross-assembly namespace renames -- Mono.Posix.dll
uses a Mono_Posix C namespace, but the default algorithm would be a
Mono_Unix_Native prefix. Thus, two choices for correct behavior: use
MapAttribute.ExportPrefix within Mono.Posix.dll, allowing all consumers to
get the correct prefix By Default (It Just Works), or require that all
consumers add --rename-namespace arguments (more clunky, more difficult to
diagnose, not as "version proof").
2006-08-20 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/make-map.cs: Add new arguments: --autoconf-member,
--exclude-native-symbol, --library, --rename-member, --rename-namespace.
These are to remove the necessity of
Mono.Unix.Native.MapAttribute.Optional (--autoconf-member) and
MapAttribute.ExportPrefix (--rename-namespace), while adding much needed
support for the DllImport libraries to generate prototypes for
(--library), symbol exclusion (to remove Mono_Posix_Stdlib_snprintf;
--exclude-native-symbol), and member renaming (curse you glibc making
st_atime a macro! See --rename-member).
* lib/mono-fuse/Makefile: Use new make-map.exe arguments to test their
behavior when building test.c/test.h.
* lib/mono-fuse/MakeMap.Test.cs: Add types/members to test new make-map.cs
arguments.
* lib/mono-fuse/test.c.ref, lib/mono-fuse/test.h.ref: Flush (new expected
2006-08-20 Jonathan Pryor <jonpryor@vt.edu>
* lib/map.c, lib/map.h: Flush.
* lib/mono-fuse/FileSystem.cs: Use Mono.Unix.Native.MapHeaderAttribute
instead of Mono.Unix.Native.HeaderAttribute.
2006-08-17 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/make-map.cs: Add a newline after the implementation macro section.
2006-08-17 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/MakeMap.Test.cs: Use of
MapHeaderAttribute.ImplementationMacro and
MapHeaderAttribute.ImplementationIncludeFile.
* lib/mono-fuse/make-map.cs: Add support for
MapHeaderAttribute.Implementation* properties within the .c file.
* lib/mono-fuse/test.c.ref, lib/mono-fuse/test.h.ref: Sync with current
make-map.exe output.
2006-08-16 Jonathan Pryor <jonpryor@vt.edu>
* lib/map.c, lib.map.h: Flush (new formatting due to make-map changes
* lib/mono-fuse/MakeMap.Test.cs: Use MapHeaderAttribute; remove
[Map("struct qux")] from Qux (can't compile this).
* lib/mono-fuse/Makefile: Improve dependencies to ensure things are rebuilt
when needed; add libtest.so target (to make sure test.c is valid C).
* lib/mono-fuse/make-map.cs: Add support for Mono.Unix.Native.MapHeaderAttribute;
formatting improvements.
* lib/mono-fuse/test.c.ref, lib/mono-fuse/test.h.ref: Flush.
2006-08-14 Jonathan Pryor <jonpryor@vt.edu>
API Cleanup -- return values should only be for reporting errors, not for
reporting additional information (e.g. read(2) & write(2) overload the return
value; we don't want to do that, as it's inconsistent).
* lib/map.h: Sync with mono-fuse/FileSystem.cs
* lib/mfh.c (mfh_read, mfh_write, mfh_setxattr, mfh_listxattr): Add
additional argument to get number bytes read/written from buffer.
* lib/mono-fuse/FileSystem.cs: Change ReadCb(), WriteCb(),
GetExtendedAttributesCb(), ListExtendedAttributesCb() so that return type
is Errno (consistency) and an extra `out' parameter is added to hold the
number of bytes read/written from the buffer.
* lib/mono-fuse/HelloFS.cs: Sync with latest API.
2006-08-14 Jonathan Pryor <jonpryor@vt.edu>
Re-enable bounds checking in struct/class conversion functions; API cleanup.
* lib/map.h: Sync with FileSystem.cs
* lib/mph.c: Add more conversion functions.
* lib/mfh.c: Fully implement all forwarding functions; remove some warnings;
fix segfault in _free_argv().
* lib/mono-fuse/FileSystem.cs: Use properties, not public fields; add
OpenReadOnly, OpenWriteOnly, OpenReadWrite helpers (to remove ugly
((OpenFlags) ((int) fi.Flags & 3)) == OpenFlags.O_RDONLY sillyness). Stat
and Statvfs are `out', not `ref'. Correct marshaling of byte[]s within
delegates, as some are `const' and some aren't (so no need to copy-in or
copy-out if not appropriate). Use mfh_fuse_ prefix instead of mfh_.
* lib/mono-fuse/HelloFS.cs: Use latest API.
2006-08-09 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/FileSystem.cs:
- Remove DestroyCb() delegate, OnDestroy() method. It's not needed, as
FileSystem.Dispose() cleans up opsp, and OnDestroy() was only called
from fuse_destroy(), which is also invoked from Dispose().
- Add wrappers for all protected virtual methods to act as a "backstop"
for exceptions. We cannot allow exceptions to enter native code from
managed code (as this would likely kill the process, with Mono's
exception handler "cleaning up" the native callstack, which can't make
FUSE happy). If an exception is emitted, EIO is returned to FUSE.
These methods can also be used to remove unnecessary parameters, such as
the `WriteCb' `size' parameter (which becomes buf.Length).
* lib/mono-fuse/HelloFS.cs: Add a `data' file, which contains 96MB of plain
text data (useful for timing analysis to see the overhead from
various forms of marshaling). Update to use new OnRead() parameters.
2006-08-08 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/FileSystem.cs: Correct FUSE argument parsing (bad regex used).
GetFuseArgs() needs to prepend the executable name for proper FUSE operation.
We're now able to start an app and pass `-d' to get FUSE debugging messages.
2006-08-08 Jonathan Pryor <jonpryor@vt.edu>
Flush.
2006-08-08 Jonathan Pryor <jonpryor@vt.edu>
Get things (somewhat) working -- we're now able to read a file contents
through FUSE, but we're not able to opendir/readdir. :-/
* lib/Makefile: Add -g, and libMonoFuseHelper.so should link to
libMonoPosixHelper.so.
* lib/map.h: Synchronize with FileSystem.cs
* lib/mfh.c: Disable some functions so that I don't need to write as many
stub functions in lib/mph.c; fix mfh_read, mfh_write (return value
nonsense; this needs to be fixed later).
* lib/mono-fuse/FileSystem.cs: Fix prototypes of ReadCb and WriteCb
delegates, as we need [MarshalAs] declarations on the byte[] arrays so
that the marshaler knows what to do with them. Update all byte[] usage
within delegates. Mono doesn't like ``[Out] out string[] paths'' (as used
in ReadDirectoryCb()), so replace with `out IntPtr paths' and manually
marshal the string[].
* lib/mono-fuse/Makefile: Use global Mono.Posix.dll file, not local copy;
* add `hellofs' target to run HelloFS.exe with LD_LIBRARY_PATH set.
* lib/mono-fuse/HelloFS.cs: Add C.WL helpers (for tracing); fix OnOpen() so
that we can read a file (it's O_RDONLY check was wrong); print out parsed
command line arguments (showing that FileSystem.Parse() is broken --
that's next to fix).
* lib/mono-fuse/make-map.cs: Don't insert types into `structs' table when a
type with [Map] is found, use RecordTypes() instead (so that we record all
nested types as well). Warnings should be prefixed with "warning: ".
Don't always generate Namespace_ToType/Namespace_FromType declarations,
but only if MapAttribute.NativeType was specified. Allows for [Map] on
structures that need to be exported from an assembly but aren't used
within shared methods.
* lib/mph.c: Let this compile.
2006-08-05 Jonathan Pryor <jonpryor@vt.edu>
Include all correct .o files into libMonoFuseHelper.so
Use correct return types in fuse_* methods.
2006-08-05 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/FileSystem.cs: Remove [Map] from Mono.Fuse.Operations, as it
cannot be assigned to `struct fuse_operations'. Add necessary DllImport's.
* lib/mono-fuse/HelloFS.cs: Fix to match new OnReadDirectory() prototype.
2006-08-05 Jonathan Pryor <jonpryor@vt.edu>
* lib/mfh.c: Add implementation of mfh_readdir().
2006-08-05 Jonathan Pryor <jonpryor@vt.edu>
* lib/mono-fuse/FileSystem.cs: Add necessary Header attribute so that map.c/map.h are
generated sanely.
2006-08-05 Jonathan Pryor <jonpryor@vt.edu>
Add unit test for make-map.exe, check & check-update targets to Makefile, and
expected output for unit tests.
2006-08-02 Jonathan Pryor <jonpryor@vt.edu>
Provide implementations for most of the mfh_* functions.
Remove backup files.
2006-08-02 Jonathan Pryor <jonpryor@vt.edu>
Build libMonoFuseHelper.so.
2006-08-01 Jonathan Pryor <jonpryor@vt.edu>
Add files for libMonoFuseHelper.so and Makefile to build libMonoFuseHelper.so.
2006-08-01 Jonathan Pryor <jonpryor@vt.edu>
Current Mono.Fuse managed code implementation.
2006-07-22 Jonathan Pryor <jonpryor@vt.edu>
Initial Import.

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>CreateNativeMap</PackageId>
<PackageVersion>1.0.0</PackageVersion>
<Authors>Miguel de Icaza, Jonathan Pryor, Alexey Kolpakov</Authors>
<Description>Port of mono's `create-native-map` tool to NET Standart</Description>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0-beta3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.Fuse.NETStandard\Mono.Fuse.NETStandard.csproj" />
</ItemGroup>
</Project>

1942
CreateNativeMap/Program.cs Normal file

File diff suppressed because it is too large Load Diff

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
Copyright (C) 2006 Jonathan Pryor
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

47
Mono.Fuse.NETStandard.sln Normal file
View File

@@ -0,0 +1,47 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Fuse.NETStandard", "Mono.Fuse.NETStandard\Mono.Fuse.NETStandard.csproj", "{247EAF60-7B35-444D-9B7D-13CBD76B7FA7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloFS", "example\HelloFS\HelloFS.csproj", "{FF21B641-C21D-401B-9450-E68DFDA09C07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateNativeMap", "CreateNativeMap\CreateNativeMap.csproj", "{7F34C644-632E-4271-A1F9-114037DF6311}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedirectFS", "example\RedirectFS\RedirectFS.csproj", "{11E71BC7-004B-4CB5-BA03-86E160199D78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedirectFS-FH", "example\RedirectFS-FH\RedirectFS-FH.csproj", "{1D5F7569-C773-422B-B783-3F1775816D45}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{85A3668F-D9E7-4794-8723-4F3767008CB9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{247EAF60-7B35-444D-9B7D-13CBD76B7FA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{247EAF60-7B35-444D-9B7D-13CBD76B7FA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{247EAF60-7B35-444D-9B7D-13CBD76B7FA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{247EAF60-7B35-444D-9B7D-13CBD76B7FA7}.Release|Any CPU.Build.0 = Release|Any CPU
{FF21B641-C21D-401B-9450-E68DFDA09C07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF21B641-C21D-401B-9450-E68DFDA09C07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF21B641-C21D-401B-9450-E68DFDA09C07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF21B641-C21D-401B-9450-E68DFDA09C07}.Release|Any CPU.Build.0 = Release|Any CPU
{7F34C644-632E-4271-A1F9-114037DF6311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F34C644-632E-4271-A1F9-114037DF6311}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F34C644-632E-4271-A1F9-114037DF6311}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F34C644-632E-4271-A1F9-114037DF6311}.Release|Any CPU.Build.0 = Release|Any CPU
{11E71BC7-004B-4CB5-BA03-86E160199D78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11E71BC7-004B-4CB5-BA03-86E160199D78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11E71BC7-004B-4CB5-BA03-86E160199D78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11E71BC7-004B-4CB5-BA03-86E160199D78}.Release|Any CPU.Build.0 = Release|Any CPU
{1D5F7569-C773-422B-B783-3F1775816D45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D5F7569-C773-422B-B783-3F1775816D45}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D5F7569-C773-422B-B783-3F1775816D45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D5F7569-C773-422B-B783-3F1775816D45}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{11E71BC7-004B-4CB5-BA03-86E160199D78} = {85A3668F-D9E7-4794-8723-4F3767008CB9}
{1D5F7569-C773-422B-B783-3F1775816D45} = {85A3668F-D9E7-4794-8723-4F3767008CB9}
{FF21B641-C21D-401B-9450-E68DFDA09C07} = {85A3668F-D9E7-4794-8723-4F3767008CB9}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,79 @@
//
// Mono.Fuse/FileNameMarshaler.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2005 Jonathan Pryor
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.InteropServices;
using Mono.Unix;
namespace Mono.Fuse.NETStandard {
class FileNameMarshaler : ICustomMarshaler {
private static FileNameMarshaler Instance = new FileNameMarshaler ();
public static ICustomMarshaler GetInstance (string s)
{
return Instance;
}
public void CleanUpManagedData (object o)
{
}
public void CleanUpNativeData (IntPtr pNativeData)
{
// Console.WriteLine ("# FileNameMarshaler.CleanUpManagedData ({0:x})", pNativeData);
UnixMarshal.FreeHeap (pNativeData);
}
public int GetNativeDataSize ()
{
return IntPtr.Size;
}
public IntPtr MarshalManagedToNative (object obj)
{
string s = obj as string;
if (s == null)
return IntPtr.Zero;
IntPtr p = UnixMarshal.StringToHeap (s, UnixEncoding.Instance);
// Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged for `{0}'={1:x}", s, p);
return p;
}
public object MarshalNativeToManaged (IntPtr pNativeData)
{
string s = UnixMarshal.PtrToString (pNativeData, UnixEncoding.Instance);
// Console.WriteLine ("# FileNameMarshaler.MarshalNativeToManaged ({0:x})=`{1}'",
// pNativeData, s);
return s;
}
}
}
// vim: noexpandtab

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
//
// MapAttribute.cs
//
// Author:
// Miguel de Icaza (miguel@gnome.org)
//
// (C) Novell, Inc.
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace Mono.Fuse.NETStandard
{
[AttributeUsage (
AttributeTargets.Class |
AttributeTargets.Delegate |
AttributeTargets.Enum |
AttributeTargets.Field |
AttributeTargets.Struct)]
public class MapAttribute : Attribute {
public MapAttribute ()
{
}
public MapAttribute (string nativeType)
{
NativeType = nativeType;
}
public string NativeType { get; }
public string SuppressFlags { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Mono.Fuse.NETStandard</PackageId>
<PackageVersion>1.0.0-pre1</PackageVersion>
<Authors>Jonathan Pryor, Alexey Kolpakov</Authors>
<Description>Port of Mono.Fuse package to NET Standart: C# bindings for FUSE</Description>
<PackageTags>mono fuse filesystem linux unix</PackageTags>
<RootNamespace>Mono.Fuse.NETStandard</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="..\nativelibs\linux-x64\libMonoFuseHelper.so">
<PackagePath>runtimes/linux-x64/native/libMonoFuseHelper.so</PackagePath>
<Pack>true</Pack>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0-beta3" />
</ItemGroup>
</Project>

493
MonoFuseHelper/mfh.c Normal file
View File

@@ -0,0 +1,493 @@
/*
* mfh.c: MonoFuseHelper implementation.
*
* Authors:
* Jonathan Pryor (jonpryor@vt.edu)
*
* Copyright (C) 2006 Jonathan Pryor
*/
/*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define FUSE_USE_VERSION 26
#include <map.h>
#include <fuse.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static inline struct Mono_Fuse_NETStandard_Operations*
_mfh_get_private_data ()
{
return (struct Mono_Fuse_NETStandard_Operations*) fuse_get_context()->private_data;
}
static int
mfh_getattr (const char *path, struct stat *stat)
{
return _mfh_get_private_data ()->getattr (path, stat);
}
static int
mfh_readlink (const char *path, char* buf, size_t size)
{
return _mfh_get_private_data ()->readlink (path, buf, size);
}
static int
mfh_mknod (const char *path, mode_t mode, dev_t dev)
{
return _mfh_get_private_data ()->mknod (path, mode, dev);
}
static int
mfh_mkdir (const char *path, mode_t mode)
{
return _mfh_get_private_data ()->mkdir (path, mode);
}
static int
mfh_unlink (const char *path)
{
return _mfh_get_private_data ()->unlink (path);
}
static int
mfh_rmdir (const char *path)
{
return _mfh_get_private_data ()->rmdir (path);
}
static int
mfh_symlink (const char *oldpath, const char *newpath)
{
return _mfh_get_private_data ()->symlink (oldpath, newpath);
}
static int
mfh_rename (const char *oldpath, const char *newpath)
{
return _mfh_get_private_data ()->rename (oldpath, newpath);
}
static int
mfh_link (const char *oldpath, const char *newpath)
{
return _mfh_get_private_data ()->link (oldpath, newpath);
}
static int
mfh_chmod (const char *path, mode_t mode)
{
return _mfh_get_private_data ()->chmod (path, mode);
}
static int
mfh_chown (const char *path, uid_t uid, gid_t gid)
{
return _mfh_get_private_data ()->chown (path, uid, gid);
}
static int
mfh_truncate (const char *path, off_t len)
{
return _mfh_get_private_data ()->truncate (path, len);
}
static int
mfh_utime (const char *path, struct utimbuf *buf)
{
return _mfh_get_private_data ()->utime (path, buf);
}
int
Mono_Fuse_NETStandard_ToOpenedPathInfo (void *_from, struct Mono_Fuse_NETStandard_OpenedPathInfo *to)
{
struct fuse_file_info *from = _from;
memset (to, 0, sizeof (*to));
to->flags = from->flags;
to->write_page = from->writepage;
to->direct_io = from->direct_io;
to->keep_cache = from->keep_cache;
to->file_handle = from->fh;
return 0;
}
int
Mono_Fuse_NETStandard_FromOpenedPathInfo (struct Mono_Fuse_NETStandard_OpenedPathInfo *from, void *_to)
{
struct fuse_file_info *to = _to;
memset (to, 0, sizeof (*to));
to->flags = from->flags;
to->writepage = from->write_page;
to->direct_io = from->direct_io ? 1 : 0;
to->keep_cache = from->keep_cache ? 1 : 0;
to->fh = from->file_handle;
return 0;
}
static int
mfh_open (const char *path, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->open (path, info);
return r;
}
static int
mfh_read (const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *info)
{
int r, bytesRead = 0;
r = _mfh_get_private_data ()->read (path, (unsigned char*) buf, size, offset,
info, &bytesRead);
if (r == 0 && bytesRead >= 0)
return bytesRead;
return r;
}
static int
mfh_write (const char *path, const char *buf, size_t size, off_t offset,
struct fuse_file_info *info)
{
int r, bytesWritten = 0;
r = _mfh_get_private_data ()->write (path, (unsigned char*) buf, size, offset,
info, &bytesWritten);
if (r == 0 && bytesWritten >= 0)
return bytesWritten;
return r;
}
static int
mfh_statfs (const char *path, struct statvfs *buf)
{
return _mfh_get_private_data ()->statfs (path, buf);
}
static int
mfh_flush (const char *path, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->flush (path, info);
return r;
}
static int
mfh_release (const char *path, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->release (path, info);
return r;
}
static int
mfh_fsync (const char *path, int onlyUserData, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->fsync (path, onlyUserData, info);
return r;
}
static int
mfh_setxattr (const char *path, const char *name, const char *value, size_t size, int flags)
{
return _mfh_get_private_data ()->setxattr (path, name, (unsigned char*) value, size, flags);
}
static int
mfh_getxattr (const char *path, const char *name, char *buf, size_t size)
{
int r, bytesWritten = 0;
r = _mfh_get_private_data ()->getxattr (path, name, (unsigned char *) buf,
size, &bytesWritten);
if (r == 0 && bytesWritten >= 0)
return bytesWritten;
return r;
}
static int
mfh_listxattr (const char *path, char *buf, size_t size)
{
int r, bytesWritten = 0;
r = _mfh_get_private_data ()->listxattr (path, (unsigned char *) buf, size,
&bytesWritten);
if (r == 0 && bytesWritten >= 0)
return bytesWritten;
return r;
}
static int
mfh_removexattr (const char *path, const char *name)
{
return _mfh_get_private_data ()->removexattr (path, name);
}
static int
mfh_opendir (const char *path, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->opendir (path, info);
return r;
}
static int
mfh_readdir (const char *path, void* buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *info)
{
int r;
struct stat stbuf;
r = _mfh_get_private_data ()->readdir (path, buf, filler, offset, info, &stbuf);
return r;
}
int
mfh_invoke_filler (void *_filler, void *buf, const char *path, void *_stbuf, gint64 offset)
{
struct stat *stbuf = _stbuf;
fuse_fill_dir_t filler = _filler;
return filler (buf, path, stbuf, (off_t) offset);
}
static int
mfh_releasedir (const char *path, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->releasedir (path, info);
return r;
}
static int
mfh_fsyncdir (const char *path, int onlyUserData, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->fsyncdir (path, onlyUserData, info);
return r;
}
void
mfh_destroy (void* user_data)
{
_mfh_get_private_data ()->destroy (user_data);
}
static int
mfh_access (const char *path, int flags)
{
return _mfh_get_private_data ()->access (path, flags);
}
static int
mfh_create (const char *path, mode_t mode, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->create (path, mode, info);
return r;
}
static int
mfh_ftruncate (const char *path, off_t len, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->ftruncate (path, len, info);
return r;
}
static int
mfh_fgetattr (const char *path, struct stat *stat, struct fuse_file_info *info)
{
int r;
r = _mfh_get_private_data ()->fgetattr (path, stat, info);
return r;
}
static int
mfh_lock (const char *path, struct fuse_file_info *info, int cmd, struct flock *lock)
{
int r;
r = _mfh_get_private_data ()->lock (path, info, cmd, lock);
return r;
}
static int
mfh_bmap (const char *path, size_t blocksize, uint64_t *idx)
{
int r;
r = _mfh_get_private_data ()->bmap (path, blocksize, idx);
return r;
}
static void
_to_fuse_operations (struct Mono_Fuse_NETStandard_Operations *from, struct fuse_operations *to)
{
memset (to, 0, sizeof(*to));
if (from->getattr) to->getattr = mfh_getattr;
if (from->readlink) to->readlink = mfh_readlink;
if (from->mknod) to->mknod = mfh_mknod;
if (from->mkdir) to->mkdir = mfh_mkdir;
if (from->unlink) to->unlink = mfh_unlink;
if (from->rmdir) to->rmdir = mfh_rmdir;
if (from->symlink) to->symlink = mfh_symlink;
if (from->rename) to->rename = mfh_rename;
if (from->link) to->link = mfh_link;
if (from->chmod) to->chmod = mfh_chmod;
if (from->chown) to->chown = mfh_chown;
if (from->truncate) to->truncate = mfh_truncate;
if (from->utime) to->utime = mfh_utime;
if (from->open) to->open = mfh_open;
if (from->read) to->read = mfh_read;
if (from->write) to->write = mfh_write;
if (from->statfs) to->statfs = mfh_statfs;
if (from->flush) to->flush = mfh_flush;
if (from->release) to->release = mfh_release;
if (from->fsync) to->fsync = mfh_fsync;
if (from->setxattr) to->setxattr = mfh_setxattr;
if (from->getxattr) to->getxattr = mfh_getxattr;
if (from->listxattr) to->listxattr = mfh_listxattr;
if (from->removexattr) to->removexattr = mfh_removexattr;
if (from->opendir) to->opendir = mfh_opendir;
if (from->readdir) to->readdir = mfh_readdir;
if (from->releasedir) to->releasedir = mfh_releasedir;
if (from->fsyncdir) to->fsyncdir = mfh_fsyncdir;
if (from->init) to->init = (void* (*)(struct fuse_conn_info*)) from->init;
if (from->destroy) to->destroy = mfh_destroy;
if (from->access) to->access = mfh_access;
if (from->create) to->create = mfh_create;
if (from->ftruncate) to->ftruncate = mfh_ftruncate;
if (from->fgetattr) to->fgetattr = mfh_fgetattr;
if (from->lock) to->lock = mfh_lock;
if (from->bmap) to->bmap = mfh_bmap;
}
void
mfh_show_fuse_help (const char *appname)
{
char *help[3];
char *mountpoint;
int mt, foreground;
struct fuse_args args;
struct fuse_operations ops = {};
help [0] = (char*) appname;
help [1] = "-ho";
help [2] = NULL;
memset (&args, 0, sizeof(args));
args.argc = 2;
args.argv = help;
args.allocated = 0;
fuse_parse_cmdline (&args, &mountpoint, &mt, &foreground);
fuse_mount ("mountpoint", &args);
fuse_new (NULL, &args, &ops, sizeof(ops), NULL);
fuse_opt_free_args (&args);
}
int
mfh_fuse_get_context (struct Mono_Fuse_NETStandard_FileSystemOperationContext* context)
{
struct fuse_context *from = fuse_get_context ();
if (from == NULL) {
errno = ENOTSUP;
return -1;
}
context->fuse = from->fuse;
context->userId = from->uid;
context->groupId = from->gid;
context->processId = from->pid;
return 0;
}
int
mfh_fuse_main (int argc, void *argv, void* ops)
{
struct Mono_Fuse_NETStandard_Operations *mops;
struct fuse_operations fops;
int r;
mops = (struct Mono_Fuse_NETStandard_Operations*) ops;
_to_fuse_operations (mops, &fops);
r = fuse_main (argc, argv, &fops, NULL);
return r;
}
void
mfh_fuse_exit (void *fusep)
{
fuse_exit ((struct fuse*) fusep);
}
int
mfh_fuse_loop (void *fusep)
{
return fuse_loop ((struct fuse*) fusep);
}
int
mfh_fuse_loop_mt (void *fusep)
{
return fuse_loop_mt ((struct fuse*) fusep);
}

88
README Normal file
View File

@@ -0,0 +1,88 @@
This is a Mono/.NET binding for FUSE.
Short HOWTO:
Within one terminal:
sudo /sbin/modprobe fuse # need FUSE kernel module to use.
./configure
make
cd example/HelloFS
mkdir t
./hellofs t
Within another terminal
cd example/HelloFS
ls t
cat t/hello
This should display files controlled by HelloFS.exe.
To unmount the filesystem, you need to use the `fusermount' program:
cd example/HelloFS
fusermount -u t
KILLING THE FUSE PROGRAM IS NOT ENOUGH. The program will die, but
FUSE and the kernel will still think that the directory is mounted.
Result: you can't remount the directory, and trying to do anything
with it will result in IO errors.
For full trace output, set the MONO_TRACE_LISTENER environment
variable and add the -odebug command-line argument:
cd example/HelloFS
MONO_TRACE_LISTENER=Console.Out### ./hellofs -odebug t
MONO_TRACE_LISTENER controls the Mono.Fuse trace output, while
-odebug controls the libfuse-generated trace output.
`hellofs' also takes its own command-line aruments. By default,
it exports two files, `data' and `hello'. `hello' contains the
string "Hello World!", while `data' is a 100 MB (base 10) file that
generates its content on-demand.
If you pass the --data.im-in-memory flag, a `data.im' file will be
available which is a 100MB (base 10) file with the same contents as
`data', but it is backed by a 100MB byte[] instead of generating its
contents on demand:
cd example/HelloFS
./hellofs --data.im-in-memory t
The 100MB byte[] is allocated the first time the contents of
`data.im' are read.
`data.im' is useful to see the difference in performance between
generate-on-demand and cached behaviors:
cd example/HelloFS
./hellofs --data.im-in-memory t
# On-demand copy
time cp t/data f.txt
real 0m8.469s
user 0m0.020s
sys 0m1.128s
# In-memory copy
# Note that the first `data.im' access is longer
# because it needed to allocate the array.
# Subsequent calls are shorter:
time \cp -f t/data.im f.txt
real 0m12.393s
user 0m0.004s
sys 0m1.172s
time \cp -f t/data.im f.txt
real 0m5.233s
user 0m0.016s
sys 0m1.136s
# And for comparison, cp without FUSE:
time cp f.txt f2.txt
real 0m10.252s
user 0m0.016s
sys 0m1.000s
And yes, on my machine it's faster to go through FUSE than to go
through the filesystem (though usually the filesystem outperforms
the on-demand generation). My machine is probably misconfigured. :-/
Your mileage will vary.

40
build-libs.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/sh
assert_exists () {
if ! type "$1" 2> /dev/null 1>&2 ; then
echo "Error: '$1' not installed"
exit 1
fi
}
init_configuration () {
if [ ! -z $1 ]
then
CONFIGURATION="$1"
else
CONFIGURATION="Release"
fi
}
build_managed () {
dotnet build Mono.Fuse.NETStandard/Mono.Fuse.NETStandard.csproj -c "$CONFIGURATION"
}
build_native () {
dotnet run -p CreateNativeMap/CreateNativeMap.csproj -c "$CONFIGURATION" --library=MonoFuseHelper "Mono.Fuse.NETStandard/bin/$CONFIGURATION/netstandard2.0/Mono.Fuse.NETStandard.dll" buildlibs/map
INCLUDES="-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/fuse -Ibuildlibs/"
libtool --mode=compile gcc -D_FILE_OFFSET_BITS=64 $INCLUDES -g -O2 -MT buildlibs/mfh.lo -MD -MP -c -o buildlibs/mfh.lo MonoFuseHelper/mfh.c
libtool --mode=compile gcc -D_FILE_OFFSET_BITS=64 $INCLUDES -g -O2 -MT buildlibs/map.lo -MD -MP -c -o buildlibs/map.lo buildlibs/map.c
libtool --mode=link gcc -g -O2 -no-undefined -avoid-version -o buildlibs/libMonoFuseHelper.la -rpath /usr/local/lib buildlibs/mfh.lo buildlibs/map.lo -lglib-2.0 -lfuse -pthread
mv buildlibs/.libs/libMonoFuseHelper.so "nativelibs/linux-x64"
}
assert_exists dotnet
assert_exists libtool
assert_exists gcc
init_configuration
build_managed
build_native

270
example/HelloFS/HelloFS.cs Normal file
View File

@@ -0,0 +1,270 @@
//
// HelloFS.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2006 Jonathan Pryor
//
// Mono.Fuse.NETStandard example program
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Mono.Unix.Native;
namespace Mono.Fuse.NETStandard.Samples {
internal class HelloFs : FileSystem {
static readonly byte[] hello_str = Encoding.UTF8.GetBytes ("Hello World!\n");
const string hello_path = "/hello";
const string data_path = "/data";
const string data_im_path = "/data.im";
const int data_size = 100000000;
byte[] data_im_str;
bool have_data_im = false;
object data_im_str_lock = new object ();
Dictionary<string, byte[]> hello_attrs = new Dictionary<string, byte[]>();
public HelloFs ()
{
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
Trace.WriteLine ("(HelloFS creating)");
hello_attrs ["foo"] = Encoding.UTF8.GetBytes ("bar");
}
protected override Errno OnGetPathStatus (string path, out Stat stbuf)
{
Trace.WriteLine ("(OnGetPathStatus {0})", path);
stbuf = new Stat ();
switch (path) {
case "/":
stbuf.st_mode = FilePermissions.S_IFDIR |
NativeConvert.FromOctalPermissionString ("0755");
stbuf.st_nlink = 2;
return 0;
case hello_path:
case data_path:
case data_im_path:
stbuf.st_mode = FilePermissions.S_IFREG |
NativeConvert.FromOctalPermissionString ("0444");
stbuf.st_nlink = 1;
int size = 0;
switch (path) {
case hello_path: size = hello_str.Length; break;
case data_path:
case data_im_path: size = data_size; break;
}
stbuf.st_size = size;
return 0;
default:
return Errno.ENOENT;
}
}
protected override Errno OnReadDirectory (string path, OpenedPathInfo fi,
out IEnumerable<DirectoryEntry> paths)
{
Trace.WriteLine ("(OnReadDirectory {0})", path);
paths = null;
if (path != "/")
return Errno.ENOENT;
paths = GetEntries ();
return 0;
}
private IEnumerable<DirectoryEntry> GetEntries ()
{
yield return new DirectoryEntry (".");
yield return new DirectoryEntry ("..");
yield return new DirectoryEntry ("hello");
yield return new DirectoryEntry ("data");
if (have_data_im)
yield return new DirectoryEntry ("data.im");
}
protected override Errno OnOpenHandle (string path, OpenedPathInfo fi)
{
Trace.WriteLine (string.Format ("(OnOpen {0} Flags={1})", path, fi.OpenFlags));
if (path != hello_path && path != data_path && path != data_im_path)
return Errno.ENOENT;
if (path == data_im_path && !have_data_im)
return Errno.ENOENT;
if (fi.OpenAccess != OpenFlags.O_RDONLY)
return Errno.EACCES;
return 0;
}
protected override Errno OnReadHandle (string path, OpenedPathInfo fi, byte[] buf, long offset, out int bytesWritten)
{
Trace.WriteLine ("(OnRead {0})", path);
bytesWritten = 0;
int size = buf.Length;
if (path == data_im_path)
FillData ();
if (path == hello_path || path == data_im_path) {
byte[] source = path == hello_path ? hello_str : data_im_str;
if (offset < (long) source.Length) {
if (offset + (long) size > (long) source.Length)
size = (int) ((long) source.Length - offset);
Buffer.BlockCopy (source, (int) offset, buf, 0, size);
}
else
size = 0;
}
else if (path == data_path) {
int max = System.Math.Min ((int) data_size, (int) (offset + buf.Length));
for (int i = 0, j = (int) offset; j < max; ++i, ++j) {
if ((j % 27) == 0)
buf [i] = (byte) '\n';
else
buf [i] = (byte) ((j % 26) + 'a');
}
}
else
return Errno.ENOENT;
bytesWritten = size;
return 0;
}
protected override Errno OnGetPathExtendedAttribute (string path, string name, byte[] value, out int bytesWritten)
{
Trace.WriteLine ("(OnGetPathExtendedAttribute {0})", path);
bytesWritten = 0;
if (path != hello_path) {
return 0;
}
byte[] _value;
lock (hello_attrs) {
if (!hello_attrs.ContainsKey (name))
return 0;
_value = hello_attrs [name];
}
if (value.Length < _value.Length) {
return Errno.ERANGE;
}
Array.Copy (_value, value, _value.Length);
bytesWritten = _value.Length;
return 0;
}
protected override Errno OnSetPathExtendedAttribute (string path, string name, byte[] value, XattrFlags flags)
{
Trace.WriteLine ("(OnSetPathExtendedAttribute {0})", path);
if (path != hello_path) {
return Errno.ENOSPC;
}
lock (hello_attrs) {
hello_attrs [name] = value;
}
return 0;
}
protected override Errno OnRemovePathExtendedAttribute (string path, string name)
{
Trace.WriteLine ("(OnRemovePathExtendedAttribute {0})", path);
if (path != hello_path)
return Errno.ENODATA;
lock (hello_attrs) {
if (!hello_attrs.ContainsKey (name))
return Errno.ENODATA;
hello_attrs.Remove (name);
}
return 0;
}
protected override Errno OnListPathExtendedAttributes (string path, out string[] names)
{
Trace.WriteLine ("(OnListPathExtendedAttributes {0})", path);
if (path != hello_path) {
names = new string[]{};
return 0;
}
List<string> _names = new List<string> ();
lock (hello_attrs) {
_names.AddRange (hello_attrs.Keys);
}
names = _names.ToArray ();
return 0;
}
private bool ParseArguments (string[] args)
{
for (int i = 0; i < args.Length; ++i) {
switch (args [i]) {
case "--data.im-in-memory":
have_data_im = true;
break;
case "-h":
case "--help":
Console.Error.WriteLine ("usage: hellofs [options] mountpoint");
FileSystem.ShowFuseHelp ("hellofs");
Console.Error.WriteLine ("hellofs options:");
Console.Error.WriteLine (" --data.im-in-memory Add data.im file");
return false;
default:
base.MountPoint = args [i];
break;
}
}
return true;
}
private void FillData ()
{
lock (data_im_str_lock) {
if (data_im_str != null)
return;
data_im_str = new byte [data_size];
for (int i = 0; i < data_im_str.Length; ++i) {
if ((i % 27) == 0)
data_im_str [i] = (byte) '\n';
else
data_im_str [i] = (byte) ((i % 26) + 'a');
}
}
}
public static void Main (string[] args)
{
using (HelloFs fs = new HelloFs ()) {
string[] unhandled = fs.ParseFuseArguments (args);
foreach (string key in fs.FuseOptions.Keys) {
Console.WriteLine ("Option: {0}={1}", key, fs.FuseOptions [key]);
}
if (!fs.ParseArguments (unhandled))
return;
// fs.MountAt ("path" /* , args? */);
fs.Start ();
}
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>Mono.Fuse.NETStandard.Samples</RootNamespace>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Fuse.NETStandard\Mono.Fuse.NETStandard.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0-beta3" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,421 @@
//
// RedirectFS-FH.cs: Port of
// http://fuse.cvs.sourceforge.net/fuse/fuse/example/fusexmp_fh.c?view=log
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2006 Jonathan Pryor
//
// Mono.Fuse.NETStandard example program
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Mono.Fuse.NETStandard;
using Mono.Unix.Native;
namespace Mono.Fuse.NETStandard.Samples {
class RedirectFHFS : FileSystem {
private string basedir;
public RedirectFHFS ()
{
}
protected override Errno OnGetPathStatus (string path, out Stat buf)
{
int r = Syscall.lstat (basedir+path, out buf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnGetHandleStatus (string path, OpenedPathInfo info, out Stat buf)
{
int r = Syscall.fstat ((int) info.Handle, out buf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnAccessPath (string path, AccessModes mask)
{
int r = Syscall.access (basedir+path, mask);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnReadSymbolicLink (string path, out string target)
{
target = null;
StringBuilder buf = new StringBuilder (256);
do {
int r = Syscall.readlink (basedir+path, buf);
if (r < 0) {
return Stdlib.GetLastError ();
}
else if (r == buf.Capacity) {
buf.Capacity *= 2;
}
else {
target = buf.ToString (0, r);
return 0;
}
} while (true);
}
protected override Errno OnOpenDirectory (string path, OpenedPathInfo info)
{
IntPtr dp = Syscall.opendir (basedir+path);
if (dp == IntPtr.Zero)
return Stdlib.GetLastError ();
info.Handle = dp;
return 0;
}
protected override Errno OnReadDirectory (string path, OpenedPathInfo fi,
out IEnumerable<DirectoryEntry> paths)
{
IntPtr dp = (IntPtr) fi.Handle;
paths = ReadDirectory (dp);
return 0;
}
private IEnumerable<DirectoryEntry> ReadDirectory (IntPtr dp)
{
Dirent de;
while ((de = Syscall.readdir (dp)) != null) {
DirectoryEntry e = new DirectoryEntry (de.d_name);
e.Stat.st_ino = de.d_ino;
e.Stat.st_mode = (FilePermissions) (de.d_type << 12);
yield return e;
}
}
protected override Errno OnReleaseDirectory (string path, OpenedPathInfo info)
{
IntPtr dp = (IntPtr) info.Handle;
Syscall.closedir (dp);
return 0;
}
protected override Errno OnCreateSpecialFile (string path, FilePermissions mode, ulong rdev)
{
int r;
// On Linux, this could just be `mknod(basedir+path, mode, rdev)' but
// this is more portable.
if ((mode & FilePermissions.S_IFMT) == FilePermissions.S_IFREG) {
r = Syscall.open (basedir+path, OpenFlags.O_CREAT | OpenFlags.O_EXCL |
OpenFlags.O_WRONLY, mode);
if (r >= 0)
r = Syscall.close (r);
}
else if ((mode & FilePermissions.S_IFMT) == FilePermissions.S_IFIFO) {
r = Syscall.mkfifo (basedir+path, mode);
}
else {
r = Syscall.mknod (basedir+path, mode, rdev);
}
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateDirectory (string path, FilePermissions mode)
{
int r = Syscall.mkdir (basedir+path, mode);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemoveFile (string path)
{
int r = Syscall.unlink (basedir+path);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemoveDirectory (string path)
{
int r = Syscall.rmdir (basedir+path);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateSymbolicLink (string from, string to)
{
int r = Syscall.symlink (from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRenamePath (string from, string to)
{
int r = Syscall.rename (basedir+from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateHardLink (string from, string to)
{
int r = Syscall.link (basedir+from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathPermissions (string path, FilePermissions mode)
{
int r = Syscall.chmod (basedir+path, mode);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathOwner (string path, long uid, long gid)
{
int r = Syscall.lchown (basedir+path, (uint) uid, (uint) gid);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnTruncateFile (string path, long size)
{
int r = Syscall.truncate (basedir+path, size);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnTruncateHandle (string path, OpenedPathInfo info, long size)
{
int r = Syscall.ftruncate ((int) info.Handle, size);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathTimes (string path, ref Utimbuf buf)
{
int r = Syscall.utime (basedir+path, ref buf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateHandle (string path, OpenedPathInfo info, FilePermissions mode)
{
int fd = Syscall.open (basedir+path, info.OpenFlags, mode);
if (fd == -1)
return Stdlib.GetLastError ();
info.Handle = (IntPtr) fd;
return 0;
}
protected override Errno OnOpenHandle (string path, OpenedPathInfo info)
{
int fd = Syscall.open (basedir+path, info.OpenFlags);
if (fd == -1)
return Stdlib.GetLastError ();
info.Handle = (IntPtr) fd;
return 0;
}
protected override unsafe Errno OnReadHandle (string path, OpenedPathInfo info, byte[] buf,
long offset, out int bytesRead)
{
int r;
fixed (byte *pb = buf) {
r = bytesRead = (int) Syscall.pread ((int) info.Handle,
pb, (ulong) buf.Length, offset);
}
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override unsafe Errno OnWriteHandle (string path, OpenedPathInfo info,
byte[] buf, long offset, out int bytesWritten)
{
int r;
fixed (byte *pb = buf) {
r = bytesWritten = (int) Syscall.pwrite ((int) info.Handle,
pb, (ulong) buf.Length, offset);
}
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnGetFileSystemStatus (string path, out Statvfs stbuf)
{
int r = Syscall.statvfs (basedir+path, out stbuf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnFlushHandle (string path, OpenedPathInfo info)
{
/* This is called from every close on an open file, so call the
close on the underlying filesystem. But since flush may be
called multiple times for an open file, this must not really
close the file. This is important if used on a network
filesystem like NFS which flush the data/metadata on close() */
int r = Syscall.close (Syscall.dup ((int) info.Handle));
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnReleaseHandle (string path, OpenedPathInfo info)
{
int r = Syscall.close ((int) info.Handle);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnSynchronizeHandle (string path, OpenedPathInfo info, bool onlyUserData)
{
int r;
if (onlyUserData)
r = Syscall.fdatasync ((int) info.Handle);
else
r = Syscall.fsync ((int) info.Handle);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnSetPathExtendedAttribute (string path, string name, byte[] value, XattrFlags flags)
{
int r = Syscall.lsetxattr (basedir+path, name, value, (ulong) value.Length, flags);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnGetPathExtendedAttribute (string path, string name, byte[] value, out int bytesWritten)
{
int r = bytesWritten = (int) Syscall.lgetxattr (basedir+path, name, value, (ulong) value.Length);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnListPathExtendedAttributes (string path, out string[] names)
{
int r = (int) Syscall.llistxattr (basedir+path, out names);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemovePathExtendedAttribute (string path, string name)
{
int r = Syscall.lremovexattr (basedir+path, name);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnLockHandle (string file, OpenedPathInfo info, FcntlCommand cmd, ref Flock @lock)
{
int r = Syscall.fcntl ((int) info.Handle, cmd, ref @lock);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
private bool ParseArguments (string[] args)
{
for (int i = 0; i < args.Length; ++i) {
switch (args [i]) {
case "-h":
case "--help":
ShowHelp ();
return false;
default:
if (base.MountPoint == null)
base.MountPoint = args [i];
else
basedir = args [i];
break;
}
}
if (base.MountPoint == null) {
return Error ("missing mountpoint");
}
if (basedir == null) {
return Error ("missing basedir");
}
return true;
}
private static void ShowHelp ()
{
Console.Error.WriteLine ("usage: redirectfs [options] mountpoint:");
FileSystem.ShowFuseHelp ("redirectfs-fh");
Console.Error.WriteLine ();
Console.Error.WriteLine ("redirectfs-fh options");
Console.Error.WriteLine (" basedir Directory to mirror");
}
private static bool Error (string message)
{
Console.Error.WriteLine ("redirectfs-fh: error: {0}", message);
return false;
}
public static void Main (string[] args)
{
using (RedirectFHFS fs = new RedirectFHFS ()) {
string[] unhandled = fs.ParseFuseArguments (args);
if (!fs.ParseArguments (unhandled))
return;
fs.Start ();
}
}
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>Mono.Fuse.NETStandard.Samples</RootNamespace>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Fuse.NETStandard\Mono.Fuse.NETStandard.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0-beta3" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,368 @@
//
// RedirectFS.cs: Port of
// http://fuse.cvs.sourceforge.net/fuse/fuse/example/fusexmp.c?view=log
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2006 Jonathan Pryor
//
// Mono.Fuse.NETStandard example program
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Mono.Fuse.NETStandard;
using Mono.Unix.Native;
namespace Mono.Fuse.NETStandard.Samples {
class RedirectFS : FileSystem {
private string basedir;
public RedirectFS ()
{
}
protected override Errno OnGetPathStatus (string path, out Stat buf)
{
int r = Syscall.lstat (basedir+path, out buf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnAccessPath (string path, AccessModes mask)
{
int r = Syscall.access (basedir+path, mask);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnReadSymbolicLink (string path, out string target)
{
target = null;
StringBuilder buf = new StringBuilder (256);
do {
int r = Syscall.readlink (basedir+path, buf);
if (r < 0) {
return Stdlib.GetLastError ();
}
else if (r == buf.Capacity) {
buf.Capacity *= 2;
}
else {
target = buf.ToString (0, r);
return 0;
}
} while (true);
}
protected override Errno OnReadDirectory (string path, OpenedPathInfo fi,
out IEnumerable<DirectoryEntry> paths)
{
IntPtr dp = Syscall.opendir (basedir+path);
if (dp == IntPtr.Zero) {
paths = null;
return Stdlib.GetLastError ();
}
Dirent de;
List<DirectoryEntry> entries = new List<DirectoryEntry> ();
while ((de = Syscall.readdir (dp)) != null) {
DirectoryEntry e = new DirectoryEntry (de.d_name);
e.Stat.st_ino = de.d_ino;
e.Stat.st_mode = (FilePermissions) (de.d_type << 12);
entries.Add (e);
}
Syscall.closedir (dp);
paths = entries;
return 0;
}
protected override Errno OnCreateSpecialFile (string path, FilePermissions mode, ulong rdev)
{
int r;
// On Linux, this could just be `mknod(basedir+path, mode, rdev)' but this is
// more portable.
if ((mode & FilePermissions.S_IFMT) == FilePermissions.S_IFREG) {
r = Syscall.open (basedir+path, OpenFlags.O_CREAT | OpenFlags.O_EXCL |
OpenFlags.O_WRONLY, mode);
if (r >= 0)
r = Syscall.close (r);
}
else if ((mode & FilePermissions.S_IFMT) == FilePermissions.S_IFIFO) {
r = Syscall.mkfifo (basedir+path, mode);
}
else {
r = Syscall.mknod (basedir+path, mode, rdev);
}
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateDirectory (string path, FilePermissions mode)
{
int r = Syscall.mkdir (basedir+path, mode);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemoveFile (string path)
{
int r = Syscall.unlink (basedir+path);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemoveDirectory (string path)
{
int r = Syscall.rmdir (basedir+path);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateSymbolicLink (string from, string to)
{
int r = Syscall.symlink (from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRenamePath (string from, string to)
{
int r = Syscall.rename (basedir+from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnCreateHardLink (string from, string to)
{
int r = Syscall.link (basedir+from, basedir+to);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathPermissions (string path, FilePermissions mode)
{
int r = Syscall.chmod (basedir+path, mode);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathOwner (string path, long uid, long gid)
{
int r = Syscall.lchown (basedir+path, (uint) uid, (uint) gid);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnTruncateFile (string path, long size)
{
int r = Syscall.truncate (basedir+path, size);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnChangePathTimes (string path, ref Utimbuf buf)
{
int r = Syscall.utime (basedir+path, ref buf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnOpenHandle (string path, OpenedPathInfo info)
{
return ProcessFile (basedir+path, info.OpenFlags, delegate (int fd) {return 0;});
}
private delegate int FdCb (int fd);
private static Errno ProcessFile (string path, OpenFlags flags, FdCb cb)
{
int fd = Syscall.open (path, flags);
if (fd == -1)
return Stdlib.GetLastError ();
int r = cb (fd);
Errno res = 0;
if (r == -1)
res = Stdlib.GetLastError ();
Syscall.close (fd);
return res;
}
protected override unsafe Errno OnReadHandle (string path, OpenedPathInfo info, byte[] buf,
long offset, out int bytesRead)
{
int br = 0;
Errno e = ProcessFile (basedir+path, OpenFlags.O_RDONLY, delegate (int fd) {
fixed (byte *pb = buf) {
return br = (int) Syscall.pread (fd, pb, (ulong) buf.Length, offset);
}
});
bytesRead = br;
return e;
}
protected override unsafe Errno OnWriteHandle (string path, OpenedPathInfo info,
byte[] buf, long offset, out int bytesWritten)
{
int bw = 0;
Errno e = ProcessFile (basedir+path, OpenFlags.O_WRONLY, delegate (int fd) {
fixed (byte *pb = buf) {
return bw = (int) Syscall.pwrite (fd, pb, (ulong) buf.Length, offset);
}
});
bytesWritten = bw;
return e;
}
protected override Errno OnGetFileSystemStatus (string path, out Statvfs stbuf)
{
int r = Syscall.statvfs (basedir+path, out stbuf);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnReleaseHandle (string path, OpenedPathInfo info)
{
return 0;
}
protected override Errno OnSynchronizeHandle (string path, OpenedPathInfo info, bool onlyUserData)
{
return 0;
}
protected override Errno OnSetPathExtendedAttribute (string path, string name, byte[] value, XattrFlags flags)
{
int r = Syscall.lsetxattr (basedir+path, name, value, (ulong) value.Length, flags);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnGetPathExtendedAttribute (string path, string name, byte[] value, out int bytesWritten)
{
int r = bytesWritten = (int) Syscall.lgetxattr (basedir+path, name, value, (ulong) value.Length);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnListPathExtendedAttributes (string path, out string[] names)
{
int r = (int) Syscall.llistxattr (basedir+path, out names);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnRemovePathExtendedAttribute (string path, string name)
{
int r = Syscall.lremovexattr (basedir+path, name);
if (r == -1)
return Stdlib.GetLastError ();
return 0;
}
protected override Errno OnLockHandle (string file, OpenedPathInfo info, FcntlCommand cmd, ref Flock @lock)
{
Flock _lock = @lock;
Errno e = ProcessFile (basedir+file, info.OpenFlags, fd => Syscall.fcntl (fd, cmd, ref _lock));
@lock = _lock;
return e;
}
private bool ParseArguments (string[] args)
{
for (int i = 0; i < args.Length; ++i) {
switch (args [i]) {
case "-h":
case "--help":
ShowHelp ();
return false;
default:
if (base.MountPoint == null)
base.MountPoint = args [i];
else
basedir = args [i];
break;
}
}
if (base.MountPoint == null) {
return Error ("missing mountpoint");
}
if (basedir == null) {
return Error ("missing basedir");
}
return true;
}
private static void ShowHelp ()
{
Console.Error.WriteLine ("usage: redirectfs [options] mountpoint basedir:");
FileSystem.ShowFuseHelp ("redirectfs");
Console.Error.WriteLine ();
Console.Error.WriteLine ("redirectfs options:");
Console.Error.WriteLine (" basedir Directory to mirror");
}
private static bool Error (string message)
{
Console.Error.WriteLine ("redirectfs: error: {0}", message);
return false;
}
public static void Main (string[] args)
{
using (RedirectFS fs = new RedirectFS ()) {
string[] unhandled = fs.ParseFuseArguments (args);
if (!fs.ParseArguments (unhandled))
return;
fs.Start ();
}
}
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>Mono.Fuse.NETStandard.Samples</RootNamespace>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Fuse.NETStandard\Mono.Fuse.NETStandard.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0-beta3" />
</ItemGroup>
</Project>