|
Packit |
130fc8 |
/* Implementation of Bus, a subtype of Connection.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
130fc8 |
* obtaining a copy of this software and associated documentation
|
|
Packit |
130fc8 |
* files (the "Software"), to deal in the Software without
|
|
Packit |
130fc8 |
* restriction, including without limitation the rights to use, copy,
|
|
Packit |
130fc8 |
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
130fc8 |
* of the Software, and to permit persons to whom the Software is
|
|
Packit |
130fc8 |
* furnished to do so, subject to the following conditions:
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
130fc8 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
130fc8 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
130fc8 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
130fc8 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
130fc8 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Packit |
130fc8 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Packit |
130fc8 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit |
130fc8 |
* DEALINGS IN THE SOFTWARE.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#include "dbus_bindings-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#include "conn-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyObject *
|
|
Packit |
130fc8 |
DBusPyConnection_NewForBus(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
PyObject *first = NULL, *mainloop = NULL;
|
|
Packit |
130fc8 |
DBusConnection *conn;
|
|
Packit |
130fc8 |
DBusError error;
|
|
Packit |
130fc8 |
Connection *self;
|
|
Packit |
130fc8 |
static char *argnames[] = {"address_or_type", "mainloop", NULL};
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", argnames,
|
|
Packit |
130fc8 |
&first, &mainloop)) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_error_init(&error);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (first &&
|
|
Packit |
130fc8 |
#ifdef PY3
|
|
Packit |
130fc8 |
PyUnicode_Check(first)
|
|
Packit |
130fc8 |
#else
|
|
Packit |
130fc8 |
PyBytes_Check(first)
|
|
Packit |
130fc8 |
#endif
|
|
Packit |
130fc8 |
)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
dbus_bool_t ret;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* It's a custom address. First connect to it, then register. */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
self = (Connection *)(DBusPyConnection_Type.tp_new)(cls, args, kwargs);
|
|
Packit |
130fc8 |
if (!self) return NULL;
|
|
Packit |
130fc8 |
TRACE(self);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
Py_BEGIN_ALLOW_THREADS
|
|
Packit |
130fc8 |
ret = dbus_bus_register(self->conn, &error);
|
|
Packit |
130fc8 |
Py_END_ALLOW_THREADS
|
|
Packit |
130fc8 |
if (!ret) {
|
|
Packit |
130fc8 |
DBusPyException_ConsumeError(&error);
|
|
Packit |
130fc8 |
Py_CLEAR(self);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return (PyObject *)self;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (!first || INTORLONG_CHECK(first))
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
long type;
|
|
Packit |
130fc8 |
PyObject *libdbusconn;
|
|
Packit |
130fc8 |
PyObject *new_args;
|
|
Packit |
130fc8 |
PyObject *new_kwargs;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* If the first argument isn't a string, it must be an integer
|
|
Packit |
130fc8 |
representing one of the well-known bus types. The default is
|
|
Packit |
130fc8 |
DBUS_BUS_SESSION. */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (first) {
|
|
Packit |
130fc8 |
/* on Python 2 this accepts either int or long */
|
|
Packit |
130fc8 |
type = PyLong_AsLong(first);
|
|
Packit |
130fc8 |
if (type == -1 && PyErr_Occurred())
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (type != DBUS_BUS_SESSION && type != DBUS_BUS_SYSTEM
|
|
Packit |
130fc8 |
&& type != DBUS_BUS_STARTER) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Unknown bus type %ld", type);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else {
|
|
Packit |
130fc8 |
type = DBUS_BUS_SESSION;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
Py_BEGIN_ALLOW_THREADS
|
|
Packit |
130fc8 |
conn = dbus_bus_get_private(type, &error);
|
|
Packit |
130fc8 |
Py_END_ALLOW_THREADS
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!conn) {
|
|
Packit |
130fc8 |
DBusPyException_ConsumeError(&error);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
libdbusconn = DBusPyLibDBusConnection_New (conn);
|
|
Packit |
130fc8 |
dbus_connection_unref (conn);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!libdbusconn)
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
new_args = PyTuple_Pack(2, libdbusconn, mainloop ? mainloop : Py_None);
|
|
Packit |
130fc8 |
Py_CLEAR(libdbusconn);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!new_args) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
new_kwargs = PyDict_New();
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!new_kwargs) {
|
|
Packit |
130fc8 |
Py_CLEAR(new_args);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
self = (Connection *)(DBusPyConnection_Type.tp_new)(cls, new_args,
|
|
Packit |
130fc8 |
new_kwargs);
|
|
Packit |
130fc8 |
Py_CLEAR(new_args);
|
|
Packit |
130fc8 |
Py_CLEAR(new_kwargs);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return (PyObject *)self; /* whether NULL or not */
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else {
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_TypeError, "A string address or an integer "
|
|
Packit |
130fc8 |
"bus type is required");
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyObject *
|
|
Packit |
130fc8 |
DBusPyConnection_GetUniqueName(Connection *self, PyObject *args UNUSED)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
const char *name;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
TRACE(self);
|
|
Packit |
130fc8 |
DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
|
|
Packit |
130fc8 |
Py_BEGIN_ALLOW_THREADS
|
|
Packit |
130fc8 |
name = dbus_bus_get_unique_name(self->conn);
|
|
Packit |
130fc8 |
Py_END_ALLOW_THREADS
|
|
Packit |
130fc8 |
if (!name) {
|
|
Packit |
130fc8 |
return DBusPyException_SetString("This connection has no unique name "
|
|
Packit |
130fc8 |
"yet");
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return NATIVESTR_FROMSTR(name);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyObject *
|
|
Packit |
130fc8 |
DBusPyConnection_SetUniqueName(Connection *self, PyObject *args)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
const char *old_name, *new_name;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!PyArg_ParseTuple(args, "s:set_unique_name", &new_name)) {
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
TRACE(self);
|
|
Packit |
130fc8 |
DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* libdbus will assert if we try to set a unique name when there's
|
|
Packit |
130fc8 |
* already one, so we need to make sure that can't happen.
|
|
Packit |
130fc8 |
* (Thanks, libdbus.)
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* The things that can set the unique name are:
|
|
Packit |
130fc8 |
* - this function - but we don't release the GIL, so only one instance of
|
|
Packit |
130fc8 |
* this function can run
|
|
Packit |
130fc8 |
* - dbus_bus_get - but this is only called in a __new__ or __new__-like
|
|
Packit |
130fc8 |
* function, so the new connection isn't available to other code yet
|
|
Packit |
130fc8 |
* and this function can't be called on it
|
|
Packit |
130fc8 |
* - dbus_bus_register - same as dbus_bus_get
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Code outside dbus-python shouldn't be setting the unique name, because
|
|
Packit |
130fc8 |
* we're using a private connection; we have to trust the authors
|
|
Packit |
130fc8 |
* of mainloop bindings not to do silly things like that.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
old_name = dbus_bus_get_unique_name(self->conn);
|
|
Packit |
130fc8 |
if (old_name != NULL) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "This connection already has a "
|
|
Packit |
130fc8 |
"unique name: '%s'", old_name);
|
|
Packit |
130fc8 |
return NULL;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
dbus_bus_set_unique_name(self->conn, new_name);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
Py_RETURN_NONE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* vim:set ft=c cino< sw=4 sts=4 et: */
|