Skip to content

Add support for Unix FDs #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/dbus-c++/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class DXXAPI MessageIter

char *signature() const; //returned string must be manually free()'d

bool append_unix_fd(int fd);

int get_unix_fd();

MessageIter recurse();

bool append_array(char type, const void *ptr, size_t length);
Expand Down
34 changes: 34 additions & 0 deletions include/dbus-c++/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ struct DXXAPI Signature : public std::string

struct DXXAPI Invalid {};

class DXXAPI UnixFD
{
public:
UnixFD();
explicit UnixFD(int fd);
~UnixFD();
UnixFD(const UnixFD& o);
UnixFD& operator = (const UnixFD& o);

int fd() const { return _fd; }

private:
int _fd;
};

class DXXAPI Variant
{
public:
Expand Down Expand Up @@ -241,6 +256,13 @@ template <> struct type<Signature>
return "g";
}
};
template <> struct type<UnixFD>
{
static std::string sig()
{
return "h";
}
};
template <> struct type<Invalid>
{
static std::string sig()
Expand Down Expand Up @@ -389,6 +411,12 @@ inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Sign
return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::UnixFD &val)
{
iter.append_unix_fd(val.fd());
return iter;
}

template<typename E>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
{
Expand Down Expand Up @@ -545,6 +573,12 @@ inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature
return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::UnixFD &val)
{
val = DBus::UnixFD(iter.get_unix_fd());
return ++iter;
}

extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);

template<typename E>
Expand Down
31 changes: 30 additions & 1 deletion src/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <dbus/dbus.h>
#include <cstdlib>

#if !HAVE_WIN32
#include <unistd.h>
#endif

#include "internalerror.h"
#include "message_p.h"

Expand Down Expand Up @@ -224,6 +228,18 @@ const char *MessageIter::get_signature()
return chars;
}

bool MessageIter::append_unix_fd(int fd)
{
return append_basic(DBUS_TYPE_UNIX_FD, &fd);
}

int MessageIter::get_unix_fd()
{
int fd;
get_basic(DBUS_TYPE_UNIX_FD, &fd);
return fd;
}

MessageIter MessageIter::recurse()
{
MessageIter iter(msg());
Expand Down Expand Up @@ -320,6 +336,7 @@ static bool is_basic_type(int typecode)
case 's':
case 'o':
case 'g':
case 'h':
return true;
default:
return false;
Expand All @@ -330,7 +347,19 @@ void MessageIter::copy_data(MessageIter &to)
{
for (MessageIter &from = *this; !from.at_end(); ++from)
{
if (is_basic_type(from.type()))
if (from.type() == 'h')
{
#if HAVE_WIN32
throw ErrorInvalidArgs("Unix FDs not supported under windows");
#else
debug_log("copying unix fd");

int fd = from.get_unix_fd();
to.append_unix_fd(fd);
close(fd);
#endif
}
else if (is_basic_type(from.type()))
{
debug_log("copying basic type: %c", from.type());

Expand Down
58 changes: 58 additions & 0 deletions src/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,69 @@
#include <cstdlib>
#include <stdarg.h>

#if !HAVE_WIN32
#include <errno.h>
#include <unistd.h>
#endif

#include "message_p.h"
#include "internalerror.h"

namespace DBus {

UnixFD::UnixFD()
: _fd(-1)
{
}

UnixFD::UnixFD(int fd)
: _fd(fd)
{
#if HAVE_WIN32
if (_fd != -1)
throw ErrorInvalidArgs("Unix FDs not supported under windows");
#endif
}

UnixFD::~UnixFD()
{
#if !HAVE_WIN32
if (_fd != -1)
close (_fd);
#endif
}

UnixFD::UnixFD(const UnixFD &o)
{
_fd = -1;
#if !HAVE_WIN32
if (o._fd != -1) {
_fd = dup(o._fd);
if (_fd == -1)
throw Error("dup:errno", toString(errno).c_str());
}
#endif
}

UnixFD &UnixFD::operator=(const UnixFD &o)
{
if (this == &o)
return *this;

#if !HAVE_WIN32
if (_fd != -1) {
close (_fd);
_fd = -1;
}
if (o._fd != -1) {
_fd = dup(o._fd);
if (_fd == -1)
throw Error("dup:errno", toString(errno).c_str());
}
#endif
return *this;
}

Variant::Variant()
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
{
Expand Down
1 change: 1 addition & 0 deletions tools/generator_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const char *atomic_type_to_string(char t)
{ 's', "std::string" },
{ 'o', "::DBus::Path" },
{ 'g', "::DBus::Signature" },
{ 'h', "::DBus::UnixFD" },
{ 'v', "::DBus::Variant" },
{ '\0', "" }
};
Expand Down