~ubuntu-branches/ubuntu/precise/dbus-python/precise

« back to all changes in this revision

Viewing changes to .pc/since-0.84.0.patch/_dbus_bindings/unixfd.c

  • Committer: Package Import Robot
  • Author(s): Barry Warsaw
  • Date: 2012-01-12 14:47:33 UTC
  • Revision ID: package-import@ubuntu.com-20120112144733-xtfbmgw30h0j40d2
Tags: 0.84.0-2ubuntu1
* debian/patches:
  - since-0.84.0.patch: Upstream unreleased changes from git tag
    dbus-python-0.84.0 to HEAD.  This is a precursor to the following.
  - python3-support.patch: Upstream unreleased changes from git
    `python3` branch for supporting Python 3. (LP: #893091)
* debian/rules: Enable the test suite.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Simple D-Bus types: Unix FD type.
 
2
 *
 
3
 * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
 
4
 * Copyright (C) 2010 Signove  <http://www.signove.com>
 
5
 *
 
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:
 
13
 *
 
14
 * The above copyright notice and this permission notice shall be
 
15
 * included in all copies or substantial portions of the Software.
 
16
 *
 
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.
 
25
 */
 
26
 
 
27
#include "types-internal.h"
 
28
 
 
29
PyDoc_STRVAR(UnixFd_tp_doc,
 
30
"An Unix Fd.\n"
 
31
"\n"
 
32
"Constructor::\n"
 
33
"\n"
 
34
"    dbus.UnixFd(value: int or file object[, variant_level: int]) -> UnixFd\n"
 
35
"\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"
 
38
"raised.\n"
 
39
"\n"
 
40
"UnixFd keeps a dup() (duplicate) of the supplied file descriptor. The\n"
 
41
"caller remains responsible for closing the original fd.\n"
 
42
"\n"
 
43
"``variant_level`` must be non-negative; the default is 0.\n"
 
44
"\n"
 
45
":IVariables:\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"
 
51
);
 
52
 
 
53
typedef struct {
 
54
    PyObject_HEAD
 
55
    int fd;
 
56
} UnixFdObject;
 
57
 
 
58
static PyObject *
 
59
UnixFd_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs UNUSED)
 
60
{
 
61
    UnixFdObject *self = NULL;
 
62
    PyObject *arg;
 
63
    PyObject *fdnumber;
 
64
    int fd_original, fd;
 
65
 
 
66
    if (! PyArg_ParseTuple(args, "O", &arg, NULL)) {
 
67
        return NULL;
 
68
    }
 
69
 
 
70
    if (PyInt_Check(arg)) {
 
71
        fd_original = PyInt_AsLong(arg);
 
72
        fd = dup(fd_original);
 
73
        if (fd < 0) {
 
74
            PyErr_Format(PyExc_ValueError, "Invalid file descriptor");
 
75
            return NULL;
 
76
        }
 
77
 
 
78
    } else if (PyObject_HasAttrString(arg, "fileno")) {
 
79
        fdnumber = PyObject_CallMethod(arg, "fileno", NULL);
 
80
        if (! fdnumber) {
 
81
            PyErr_Format(PyExc_ValueError, "Argument's fileno() method "
 
82
                                            "is not callable");
 
83
            return NULL;
 
84
        }
 
85
        if (! PyInt_Check(fdnumber)) {
 
86
            PyErr_Format(PyExc_ValueError, "Argument's fileno() method "
 
87
                                            "returned a non-int value");
 
88
            return NULL;
 
89
        }
 
90
        fd_original = PyInt_AsLong(fdnumber);
 
91
        Py_DECREF(fdnumber);
 
92
        fd = dup(fd_original);
 
93
        if (fd < 0) {
 
94
            PyErr_Format(PyExc_ValueError, "Invalid file descriptor from fileno()");
 
95
            return NULL;
 
96
        }
 
97
 
 
98
    } else {
 
99
        PyErr_Format(PyExc_ValueError, "Argument is not int and does not "
 
100
                                       "implement fileno() method");
 
101
        return NULL;
 
102
    }
 
103
 
 
104
    self = (UnixFdObject *) cls->tp_alloc(cls, 0);
 
105
    if (!self)
 
106
        return NULL;
 
107
 
 
108
    self->fd = fd;
 
109
 
 
110
    return (PyObject *) self;
 
111
}
 
112
 
 
113
static void
 
114
UnixFd_dealloc(UnixFdObject *self)
 
115
{
 
116
    if (self->fd >= 0) {
 
117
        close(self->fd);
 
118
        self->fd = -1;
 
119
    }
 
120
}
 
121
 
 
122
PyDoc_STRVAR(UnixFd_take__doc__,
 
123
"take() -> int\n"
 
124
"\n"
 
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"
 
128
"\n"
 
129
"This method may be called at most once; UnixFd 'forgets' the file\n"
 
130
"descriptor after it is taken.\n"
 
131
"\n"
 
132
":Raises ValueError: if this method has already been called\n"
 
133
);
 
134
static PyObject *
 
135
UnixFd_take(UnixFdObject *self)
 
136
{
 
137
    PyObject *fdnumber;
 
138
 
 
139
    if (self->fd < 0) {
 
140
        PyErr_SetString(PyExc_ValueError, "File descriptor already taken");
 
141
        return NULL;
 
142
    }
 
143
 
 
144
    fdnumber = Py_BuildValue("i", self->fd);
 
145
    self->fd = -1;
 
146
 
 
147
    return fdnumber;
 
148
}
 
149
 
 
150
int
 
151
dbus_py_unix_fd_get_fd(PyObject *self)
 
152
{
 
153
    return ((UnixFdObject *) self)->fd;
 
154
}
 
155
 
 
156
static PyMethodDef UnixFd_methods[] = {
 
157
    {"take", (PyCFunction) UnixFd_take, METH_NOARGS, UnixFd_take__doc__ },
 
158
    {NULL}
 
159
};
 
160
 
 
161
PyTypeObject DBusPyUnixFd_Type = {
 
162
    PyObject_HEAD_INIT(NULL)
 
163
    0,
 
164
    "dbus.UnixFd",
 
165
    sizeof(UnixFdObject),
 
166
    0,
 
167
    (destructor) UnixFd_dealloc,            /* tp_dealloc */
 
168
    0,                                      /* tp_print */
 
169
    0,                                      /* tp_getattr */
 
170
    0,                                      /* tp_setattr */
 
171
    0,                                      /* tp_compare */
 
172
    0,                                      /* tp_repr */
 
173
    0,                                      /* tp_as_number */
 
174
    0,                                      /* tp_as_sequence */
 
175
    0,                                      /* tp_as_mapping */
 
176
    0,                                      /* tp_hash */
 
177
    0,                                      /* tp_call */
 
178
    0,                                      /* tp_str */
 
179
    0,                                      /* tp_getattro */
 
180
    0,                                      /* tp_setattro */
 
181
    0,                                      /* tp_as_buffer */
 
182
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
183
    UnixFd_tp_doc,                          /* tp_doc */
 
184
    0,                                      /* tp_traverse */
 
185
    0,                                      /* tp_clear */
 
186
    0,                                      /* tp_richcompare */
 
187
    0,                                      /* tp_weaklistoffset */
 
188
    0,                                      /* tp_iter */
 
189
    0,                                      /* tp_iternext */
 
190
    UnixFd_methods,                         /* tp_methods */
 
191
    0,                                      /* tp_members */
 
192
    0,                                      /* tp_getset */
 
193
    0,                                      /* tp_base */
 
194
    0,                                      /* tp_dict */
 
195
    0,                                      /* tp_descr_get */
 
196
    0,                                      /* tp_descr_set */
 
197
    0,                                      /* tp_dictoffset */
 
198
    0,                                      /* tp_init */
 
199
    0,                                      /* tp_alloc */
 
200
    UnixFd_tp_new,                          /* tp_new */
 
201
};
 
202
 
 
203
dbus_bool_t
 
204
dbus_py_init_unixfd_type(void)
 
205
{
 
206
    if (PyType_Ready(&DBusPyUnixFd_Type) < 0) return 0;
 
207
 
 
208
    return 1;
 
209
}
 
210
 
 
211
dbus_bool_t
 
212
dbus_py_insert_unixfd_type(PyObject *this_module)
 
213
{
 
214
    Py_INCREF(&DBusPyUnixFd_Type);
 
215
    if (PyModule_AddObject(this_module, "UnixFd",
 
216
                           (PyObject *)&DBusPyUnixFd_Type) < 0) return 0;
 
217
    return 1;
 
218
}
 
219
 
 
220
/* vim:set ft=c cino< sw=4 sts=4 et: */