This repository has been archived by the owner on Nov 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from steffen-kiess/unixfd
Add support for Unix FD passing
- Loading branch information
Showing
29 changed files
with
1,266 additions
and
223 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// Copyright 2017 Steffen Kiess <[email protected]> | ||
// This software is made available under the MIT License | ||
// See COPYING for details | ||
|
||
using System; | ||
|
||
using DBus; | ||
using org.freedesktop.DBus; | ||
|
||
using Mono.Unix; | ||
using Mono.Unix.Native; | ||
|
||
class SignalsImpl : Signals { | ||
public event Action<UnixFD> GotFD; | ||
|
||
public void CallGotFD (UnixFD fd) { | ||
var handler = GotFD; | ||
if (handler != null) | ||
handler (fd); | ||
} | ||
} | ||
|
||
public class ManagedDBusTest | ||
{ | ||
public static void Main (string[] args) | ||
{ | ||
Bus conn; | ||
|
||
if (args.Length == 0) | ||
conn = Bus.Session; | ||
else { | ||
if (args[0] == "--session") | ||
conn = Bus.Session; | ||
else if (args[0] == "--system") | ||
conn = Bus.System; | ||
else | ||
conn = Bus.Open (args[0]); | ||
} | ||
|
||
IBus bus = conn.GetObject<IBus> ("org.freedesktop.DBus", new ObjectPath ("/org/freedesktop/DBus")); | ||
Console.WriteLine (bus.ListNames ().Length); | ||
|
||
var obj = conn.GetObject<Interface> (Constants.BusName, Constants.ObjectPath); | ||
var obj2 = conn.GetObject<Interface2> (Constants.BusName, Constants.ObjectPath); | ||
var objIntr = conn.GetObject<Introspectable> (Constants.BusName, Constants.ObjectPath); | ||
obj.Ping (); | ||
Console.WriteLine (obj.GetBytes (3).Length); | ||
|
||
Console.WriteLine ("conn.UnixFDSupported = " + conn.UnixFDSupported); | ||
if (!conn.UnixFDSupported) | ||
return; | ||
|
||
using (var disposableList = new DisposableList ()) { | ||
var res = obj.GetFD (disposableList, false); | ||
Console.WriteLine ("Got FD:"); | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + res.Handle); | ||
} | ||
using (var disposableList = new DisposableList ()) { | ||
var res = obj.GetFDList (disposableList, false); | ||
Console.WriteLine ("Got FDs:"); | ||
foreach (var fd in res) | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
} | ||
using (var disposableList = new DisposableList ()) { | ||
var res = (UnixFD[]) obj.GetFDListVariant (disposableList, false); | ||
Console.WriteLine ("Got FDs as variant:"); | ||
foreach (var fd in res) | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
} | ||
|
||
using (var disposableList = new DisposableList ()) { | ||
try { | ||
obj.GetFD (disposableList, true); | ||
throw new Exception ("Expected an exception"); | ||
} catch (Exception e) { | ||
if (!e.Message.Contains ("Throwing an exception after creating a UnixFD object")) | ||
throw; | ||
} | ||
} | ||
using (var disposableList = new DisposableList ()) { | ||
try { | ||
obj.GetFDList (disposableList, true); | ||
throw new Exception ("Expected an exception"); | ||
} catch (Exception e) { | ||
if (!e.Message.Contains ("Throwing an exception after creating a UnixFD object")) | ||
throw; | ||
} | ||
} | ||
using (var disposableList = new DisposableList ()) { | ||
try { | ||
obj.GetFDListVariant (disposableList, true); | ||
throw new Exception ("Expected an exception"); | ||
} catch (Exception e) { | ||
if (!e.Message.Contains ("Throwing an exception after creating a UnixFD object")) | ||
throw; | ||
} | ||
} | ||
|
||
// Check whether this leaks an FD | ||
obj.GetFD (null, false); | ||
obj.GetFDList (null, false); | ||
obj.GetFDListVariant (null, false); | ||
try { obj.GetFD (null, true); } catch {} | ||
try { obj.GetFDList (null, true); } catch {} | ||
try { obj.GetFDListVariant (null, true); } catch {} | ||
obj2.GetFD (false); | ||
obj2.GetFDList (false); | ||
obj2.GetFDListVariant (false); | ||
try { obj2.GetFD (true); } catch {} | ||
try { obj2.GetFDList (true); } catch {} | ||
try { obj2.GetFDListVariant (true); } catch {} | ||
|
||
var fd_ = Syscall.open ("/dev/null", OpenFlags.O_RDWR, 0); | ||
if (fd_ < 0) | ||
UnixMarshal.ThrowExceptionForLastError (); | ||
using (var fd = new UnixFD (fd_)) { | ||
obj.SendFD (fd); | ||
obj.SendFD (fd); | ||
obj.SendFDList (new UnixFD[] { fd, fd }); | ||
obj.SendFDListVariant (new UnixFD[] { fd, fd }); | ||
|
||
var impl = new SignalsImpl (); | ||
var spath = new ObjectPath ("/mono_dbus_sharp_test/Signals"); | ||
conn.Register (spath, impl); | ||
obj.RegisterSignalInterface (conn.UniqueName, spath); | ||
impl.CallGotFD (fd); | ||
} | ||
|
||
Console.WriteLine (objIntr.Introspect ().Length); | ||
|
||
obj.ListOpenFDs (); | ||
Console.WriteLine ("Open FDs:"); | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/"); | ||
} | ||
} | ||
|
||
// vim: noexpandtab | ||
// Local Variables: | ||
// tab-width: 4 | ||
// c-basic-offset: 4 | ||
// indent-tabs-mode: t | ||
// End: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2017 Steffen Kiess <[email protected]> | ||
// This software is made available under the MIT License | ||
// See COPYING for details | ||
|
||
using System; | ||
using DBus; | ||
|
||
public static class Constants { | ||
public const string BusName = "mono_dbus_sharp_test.UnixFDService"; | ||
public static readonly ObjectPath ObjectPath = new ObjectPath ("/mono_dbus_sharp_test/UnixFDService"); | ||
} | ||
|
||
[DBus.Interface ("mono_dbus_sharp_test.UnixFDService")] | ||
public interface Interface { | ||
void Ping (); | ||
|
||
void ListOpenFDs (); | ||
|
||
byte[] GetBytes (int len); | ||
|
||
UnixFD GetFD (DisposableList disposableList, bool throwError); | ||
UnixFD[] GetFDList (DisposableList disposableList, bool throwError); | ||
object GetFDListVariant (DisposableList disposableList, bool throwError); | ||
|
||
void SendFD (UnixFD fd); | ||
void SendFDList (UnixFD[] fds); | ||
void SendFDListVariant (object fds); | ||
|
||
void RegisterSignalInterface (string busName, ObjectPath path); | ||
} | ||
|
||
[DBus.Interface ("mono_dbus_sharp_test.UnixFDService")] | ||
public interface Interface2 { | ||
void Ping (); | ||
|
||
void ListOpenFDs (); | ||
|
||
byte[] GetBytes (int len); | ||
|
||
UnixFD GetFD (bool throwError); | ||
UnixFD[] GetFDList (bool throwError); | ||
object GetFDListVariant (bool throwError); | ||
|
||
void SendFD (UnixFD fd); | ||
void SendFDList (UnixFD[] fds); | ||
void SendFDListVariant (object fds); | ||
|
||
void RegisterSignalInterface (string busName, ObjectPath path); | ||
} | ||
|
||
[DBus.Interface ("mono_dbus_sharp_test.UnixFDSignals")] | ||
public interface Signals { | ||
event Action<UnixFD> GotFD; | ||
} | ||
|
||
// vim: noexpandtab | ||
// Local Variables: | ||
// tab-width: 4 | ||
// c-basic-offset: 4 | ||
// indent-tabs-mode: t | ||
// End: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2017 Steffen Kiess <[email protected]> | ||
// This software is made available under the MIT License | ||
// See COPYING for details | ||
|
||
/* | ||
PATH="$HOME/mono-master/bin:$PATH" ./autogen.sh && make -j8 | ||
make && ( cd examples && mcs -g UnixFDService.cs UnixFDInterface.cs -r ../src/dbus-sharp.dll -r Mono.Posix ) && MONO_PATH=src $HOME/mono-master/bin/mono --debug examples/UnixFDService.exe | ||
make && ( cd examples && mcs -g UnixFDClient.cs UnixFDInterface.cs -r ../src/dbus-sharp.dll -r Mono.Posix ) && MONO_PATH=src $HOME/mono-master/bin/mono --debug examples/UnixFDClient.exe | ||
python3 | ||
import dbus; dbus.SessionBus().get_object('mono_dbus_sharp_test.UnixFDService', '/mono_dbus_sharp_test/UnixFDService').GetBytes(3) | ||
import dbus; f = dbus.SessionBus().get_object('mono_dbus_sharp_test.UnixFDService', '/mono_dbus_sharp_test/UnixFDService').GetFD () | ||
*/ | ||
|
||
using System; | ||
|
||
using Mono.Unix; | ||
using Mono.Unix.Native; | ||
|
||
using DBus; | ||
using org.freedesktop.DBus; | ||
|
||
public class Impl : Interface { | ||
Connection conn; | ||
|
||
public Impl (Connection conn) | ||
{ | ||
this.conn = conn; | ||
} | ||
|
||
public void Ping () | ||
{ | ||
} | ||
|
||
public void ListOpenFDs () | ||
{ | ||
Console.WriteLine ("Open FDs:"); | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/"); | ||
} | ||
|
||
public UnixFD GetFD (DisposableList disposableList, bool throwError) | ||
{ | ||
var fd_ = Syscall.open ("/dev/null", OpenFlags.O_RDWR, 0); | ||
if (fd_ < 0) | ||
UnixMarshal.ThrowExceptionForLastError (); | ||
var fd = new UnixFD (fd_); | ||
disposableList.Add (fd); | ||
|
||
if (throwError) | ||
throw new Exception ("Throwing an exception after creating a UnixFD object"); | ||
|
||
return fd; | ||
} | ||
|
||
public UnixFD[] GetFDList (DisposableList disposableList, bool throwError) | ||
{ | ||
return new UnixFD[] { | ||
GetFD (disposableList, false), GetFD (disposableList, throwError), GetFD (disposableList, false) | ||
}; | ||
} | ||
|
||
public object GetFDListVariant (DisposableList disposableList, bool throwError) | ||
{ | ||
return GetFDList (disposableList, throwError); | ||
} | ||
|
||
public byte[] GetBytes (int len) | ||
{ | ||
return new byte[len]; | ||
} | ||
|
||
public void SendFD (UnixFD fd) | ||
{ | ||
Console.WriteLine ("Got FD as parameter:"); | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
} | ||
|
||
public void SendFDList (UnixFD[] fds) | ||
{ | ||
Console.WriteLine ("Got FDs as parameter:"); | ||
foreach (var fd in fds) | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
} | ||
|
||
public void SendFDListVariant (object fds) | ||
{ | ||
Console.WriteLine ("Got FDs as variant parameter:"); | ||
foreach (var fd in (UnixFD[]) fds) | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
} | ||
|
||
public void RegisterSignalInterface (string busName, ObjectPath path) | ||
{ | ||
Console.WriteLine ("Register for GotFD event at {0} / {1}", busName, path); | ||
conn.GetObject<Signals> (busName, path).GotFD += fd => { | ||
Console.WriteLine ("Got FD from signal:"); | ||
Mono.Unix.Native.Stdlib.system ("ls -l /proc/$PPID/fd/" + fd.Handle); | ||
}; | ||
} | ||
} | ||
|
||
public class UnixFDService | ||
{ | ||
public static void Main (string[] args) | ||
{ | ||
Bus conn; | ||
|
||
if (args.Length == 0) | ||
conn = Bus.Session; | ||
else { | ||
if (args[0] == "--session") | ||
conn = Bus.Session; | ||
else if (args[0] == "--system") | ||
conn = Bus.System; | ||
else | ||
conn = Bus.Open (args[0]); | ||
} | ||
|
||
conn.Register (Constants.ObjectPath, new Impl (conn)); | ||
|
||
if (conn.RequestName (Constants.BusName) != org.freedesktop.DBus.RequestNameReply.PrimaryOwner) | ||
throw new Exception ("Could not request name"); | ||
|
||
Console.WriteLine ("Waiting for requests..."); | ||
|
||
while (conn.IsConnected) { | ||
conn.Iterate (); | ||
} | ||
} | ||
} | ||
|
||
// vim: noexpandtab | ||
// Local Variables: | ||
// tab-width: 4 | ||
// c-basic-offset: 4 | ||
// indent-tabs-mode: t | ||
// End: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.