1
/* Simple D-Bus types: Unix FD type.
3
* Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
4
* Copyright (C) 2010 Signove <http://www.signove.com>
6
* Permission is hereby granted, free of charge, to any person
7
* obtaining a copy of this software and associated documentation
8
* files (the "Software"), to deal in the Software without
9
* restriction, including without limitation the rights to use, copy,
10
* modify, merge, publish, distribute, sublicense, and/or sell copies
11
* of the Software, and to permit persons to whom the Software is
12
* furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be
15
* included in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
* DEALINGS IN THE SOFTWARE.
27
#include "types-internal.h"
29
PyDoc_STRVAR(UnixFd_tp_doc,
34
" dbus.UnixFd(value: int or file object[, variant_level: int]) -> UnixFd\n"
36
"``value`` must be the integer value of a file descriptor, or an object that\n"
37
"implements the fileno() method. Otherwise, `ValueError` will be\n"
40
"UnixFd keeps a dup() (duplicate) of the supplied file descriptor. The\n"
41
"caller remains responsible for closing the original fd.\n"
43
"``variant_level`` must be non-negative; the default is 0.\n"
46
" `variant_level` : int\n"
47
" Indicates how many nested Variant containers this object\n"
48
" is contained in: if a message's wire format has a variant containing a\n"
49
" variant containing an Unix Fd, this is represented in Python by an\n"
50
" Unix Fd with variant_level==2.\n"
59
UnixFd_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs UNUSED)
61
UnixFdObject *self = NULL;
66
if (! PyArg_ParseTuple(args, "O", &arg, NULL)) {
70
if (PyInt_Check(arg)) {
71
fd_original = PyInt_AsLong(arg);
72
fd = dup(fd_original);
74
PyErr_Format(PyExc_ValueError, "Invalid file descriptor");
78
} else if (PyObject_HasAttrString(arg, "fileno")) {
79
fdnumber = PyObject_CallMethod(arg, "fileno", NULL);
81
PyErr_Format(PyExc_ValueError, "Argument's fileno() method "
85
if (! PyInt_Check(fdnumber)) {
86
PyErr_Format(PyExc_ValueError, "Argument's fileno() method "
87
"returned a non-int value");
90
fd_original = PyInt_AsLong(fdnumber);
92
fd = dup(fd_original);
94
PyErr_Format(PyExc_ValueError, "Invalid file descriptor from fileno()");
99
PyErr_Format(PyExc_ValueError, "Argument is not int and does not "
100
"implement fileno() method");
104
self = (UnixFdObject *) cls->tp_alloc(cls, 0);
110
return (PyObject *) self;
114
UnixFd_dealloc(UnixFdObject *self)
122
PyDoc_STRVAR(UnixFd_take__doc__,
125
"This method returns the file descriptor owned by UnixFd object.\n"
126
"Note that, once this method is called, closing the file descriptor is\n"
127
"the caller's responsibility.\n"
129
"This method may be called at most once; UnixFd 'forgets' the file\n"
130
"descriptor after it is taken.\n"
132
":Raises ValueError: if this method has already been called\n"
135
UnixFd_take(UnixFdObject *self)
140
PyErr_SetString(PyExc_ValueError, "File descriptor already taken");
144
fdnumber = Py_BuildValue("i", self->fd);
151
dbus_py_unix_fd_get_fd(PyObject *self)
153
return ((UnixFdObject *) self)->fd;
156
static PyMethodDef UnixFd_methods[] = {
157
{"take", (PyCFunction) UnixFd_take, METH_NOARGS, UnixFd_take__doc__ },
161
PyTypeObject DBusPyUnixFd_Type = {
162
PyObject_HEAD_INIT(NULL)
165
sizeof(UnixFdObject),
167
(destructor) UnixFd_dealloc, /* tp_dealloc */
173
0, /* tp_as_number */
174
0, /* tp_as_sequence */
175
0, /* tp_as_mapping */
181
0, /* tp_as_buffer */
182
Py_TPFLAGS_DEFAULT, /* tp_flags */
183
UnixFd_tp_doc, /* tp_doc */
186
0, /* tp_richcompare */
187
0, /* tp_weaklistoffset */
190
UnixFd_methods, /* tp_methods */
195
0, /* tp_descr_get */
196
0, /* tp_descr_set */
197
0, /* tp_dictoffset */
200
UnixFd_tp_new, /* tp_new */
204
dbus_py_init_unixfd_type(void)
206
if (PyType_Ready(&DBusPyUnixFd_Type) < 0) return 0;
212
dbus_py_insert_unixfd_type(PyObject *this_module)
214
Py_INCREF(&DBusPyUnixFd_Type);
215
if (PyModule_AddObject(this_module, "UnixFd",
216
(PyObject *)&DBusPyUnixFd_Type) < 0) return 0;
220
/* vim:set ft=c cino< sw=4 sts=4 et: */