ia64/xen-unstable

view tools/python/xen/lowlevel/xs/xs.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 f40c6650152e
children 99914b54f7bf
line source
1 /*
2 * Python interface to the Xen Store Daemon.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 2.1 of the GNU Lesser General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Copyright (C) 2005 Mike Wray Hewlett-Packard
18 *
19 */
21 #include <Python.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
30 #include "xs.h"
32 /** @file
33 * Python interface to the Xen Store Daemon (xs).
34 */
36 /* Needed for Python versions earlier than 2.3. */
37 #ifndef PyMODINIT_FUNC
38 #define PyMODINIT_FUNC DL_EXPORT(void)
39 #endif
41 #define PYPKG "xen.lowlevel.xs"
43 /** Python wrapper round an xs handle.
44 */
45 typedef struct XsHandle {
46 PyObject_HEAD;
47 struct xs_handle *xh;
48 } XsHandle;
50 static inline struct xs_handle *xshandle(PyObject *self)
51 {
52 struct xs_handle *xh = ((XsHandle*)self)->xh;
53 if (!xh)
54 PyErr_SetString(PyExc_RuntimeError, "invalid xenstore daemon handle");
55 return xh;
56 }
58 static inline PyObject *pyvalue_int(int val) {
59 return (val
60 ? PyInt_FromLong(val)
61 : PyErr_SetFromErrno(PyExc_RuntimeError));
62 }
64 static inline PyObject *pyvalue_str(char *val) {
65 return (val
66 ? PyString_FromString(val)
67 : PyErr_SetFromErrno(PyExc_RuntimeError));
68 }
70 #define xspy_read_doc "\n" \
71 "Read data from a path.\n" \
72 " path [string]: xenstore path\n" \
73 "\n" \
74 "Returns: [string] data read.\n" \
75 "Raises RuntimeError on error.\n" \
76 "\n"
78 static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
79 {
80 static char *kwd_spec[] = { "path", NULL };
81 static char *arg_spec = "s|";
82 char *path = NULL;
84 struct xs_handle *xh = xshandle(self);
85 char *xsval = NULL;
86 unsigned int xsval_n = 0;
87 PyObject *val = NULL;
89 if (!xh)
90 goto exit;
91 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
92 &path))
93 goto exit;
94 xsval = xs_read(xh, path, &xsval_n);
95 if (!xsval) {
96 val = pyvalue_int(0);
97 goto exit;
98 }
99 val = PyString_FromStringAndSize(xsval, xsval_n);
100 exit:
101 if (xsval)
102 free(xsval);
103 return val;
104 }
106 #define xspy_write_doc "\n" \
107 "Write data to a path.\n" \
108 " path [string] : xenstore path to write to\n." \
109 " data [string] : data to write.\n" \
110 " create [int] : create flag, default 0.\n" \
111 " excl [int] : exclusive flag, default 0.\n" \
112 "\n" \
113 "Returns: [int] 0 on success.\n" \
114 "Raises RuntimeError on error.\n" \
115 "\n"
117 static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
118 {
119 static char *kwd_spec[] = { "path", "data", "create", "excl", NULL };
120 static char *arg_spec = "ss#|ii";
121 char *path = NULL;
122 char *data = NULL;
123 int data_n = 0;
124 int create = 0;
125 int excl = 0;
127 struct xs_handle *xh = xshandle(self);
128 PyObject *val = NULL;
129 int flags = 0;
130 int xsval = 0;
132 if (!xh)
133 goto exit;
134 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
135 &path, &data, &data_n, &create, &excl))
136 goto exit;
137 if (create)
138 flags |= O_CREAT;
139 if (excl)
140 flags |= O_EXCL;
141 xsval = xs_write(xh, path, data, data_n, flags);
142 val = pyvalue_int(xsval);
143 exit:
144 return val;
145 }
147 #define xspy_ls_doc "\n" \
148 "List a directory.\n" \
149 " path [string]: path to list.\n" \
150 "\n" \
151 "Returns: [string array] list of subdirectory names.\n" \
152 "Raises RuntimeError on error.\n" \
153 "\n"
155 static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
156 {
157 static char *kwd_spec[] = { "path", NULL };
158 static char *arg_spec = "s|";
159 char *path = NULL;
161 struct xs_handle *xh = xshandle(self);
162 PyObject *val = NULL;
163 char **xsval = NULL;
164 unsigned int xsval_n = 0;
165 int i;
167 if (!xh)
168 goto exit;
169 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
170 goto exit;
171 xsval = xs_directory(xh, path, &xsval_n);
172 if (!xsval) {
173 val = pyvalue_int(0);
174 goto exit;
175 }
176 val = PyList_New(xsval_n);
177 for (i = 0; i < xsval_n; i++)
178 PyList_SetItem(val, i, PyString_FromString(xsval[i]));
179 exit:
180 return val;
181 }
183 #define xspy_mkdir_doc "\n" \
184 "Make a directory.\n" \
185 " path [string]: path to directory to create.\n" \
186 "\n" \
187 "Returns: [int] 0 on success.\n" \
188 "Raises RuntimeError on error.\n" \
189 "\n"
191 static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
192 {
193 static char *kwd_spec[] = { "path", NULL };
194 static char *arg_spec = "s|";
195 char *path = NULL;
197 struct xs_handle *xh = xshandle(self);
198 PyObject *val = NULL;
199 int xsval = 0;
201 if (!xh)
202 goto exit;
203 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
204 goto exit;
205 xsval = xs_mkdir(xh, path);
206 val = pyvalue_int(xsval);
207 exit:
208 return val;
209 }
211 #define xspy_rm_doc "\n" \
212 "Remove a path.\n" \
213 " path [string] : path to remove\n" \
214 "\n" \
215 "Returns: [int] 0 on success.\n" \
216 "Raises RuntimeError on error.\n" \
217 "\n"
219 static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
220 {
221 static char *kwd_spec[] = { "path", NULL };
222 static char *arg_spec = "s|";
223 char *path = NULL;
225 struct xs_handle *xh = xshandle(self);
226 PyObject *val = NULL;
227 int xsval = 0;
229 if (!xh)
230 goto exit;
231 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
232 goto exit;
233 xsval = xs_rm(xh, path);
234 val = pyvalue_int(xsval);
235 exit:
236 return val;
237 }
239 #define xspy_get_permissions_doc "\n" \
240 "Get the permissions for a path\n" \
241 " path [string]: xenstore path.\n" \
242 "\n" \
243 "Returns: permissions array.\n" \
244 "Raises RuntimeError on error.\n" \
245 "\n"
247 static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
248 PyObject *kwds)
249 {
250 static char *kwd_spec[] = { "path", NULL };
251 static char *arg_spec = "s|";
252 char *path = NULL;
254 struct xs_handle *xh = xshandle(self);
255 PyObject *val = NULL;
256 struct xs_permissions *perms;
257 unsigned int perms_n = 0;
258 int i;
260 if (!xh)
261 goto exit;
262 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
263 goto exit;
264 perms = xs_get_permissions(xh, path, &perms_n);
265 if (!perms) {
266 PyErr_SetFromErrno(PyExc_RuntimeError);
267 goto exit;
268 }
269 val = PyList_New(perms_n);
270 for (i = 0; i < perms_n; i++, perms++) {
271 PyObject *p = Py_BuildValue("{s:i,s:i,s:i}",
272 "dom", perms->id,
273 "read", (perms->perms & XS_PERM_READ),
274 "write", (perms->perms & XS_PERM_WRITE));
275 PyList_SetItem(val, i, p);
276 }
277 exit:
278 return val;
279 }
281 #define xspy_set_permissions_doc "\n" \
282 "Set the permissions for a path\n" \
283 " path [string] : xenstore path.\n" \
284 " perms : permissions.\n" \
285 "\n" \
286 "Returns: [int] 0 on success.\n" \
287 "Raises RuntimeError on error.\n" \
288 "\n"
290 static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
291 PyObject *kwds)
292 {
293 static char *kwd_spec[] = { "path", "perms", NULL };
294 static char *arg_spec = "sO";
295 char *path = NULL;
296 PyObject *perms = NULL;
297 static char *perm_names[] = { "dom", "read", "write", NULL };
298 static char *perm_spec = "i|iiii";
300 struct xs_handle *xh = xshandle(self);
301 int i, xsval;
302 struct xs_permissions *xsperms = NULL;
303 int xsperms_n = 0;
304 PyObject *tuple0 = NULL;
305 PyObject *val = NULL;
307 if (!xh)
308 goto exit;
309 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
310 &path, &perms))
311 goto exit;
312 if (!PyList_Check(perms)) {
313 PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
314 goto exit;
315 }
316 xsperms_n = PyList_Size(perms);
317 xsperms = calloc(xsperms_n, sizeof(struct xs_permissions));
318 if (!xsperms) {
319 PyErr_SetString(PyExc_RuntimeError, "out of memory");
320 goto exit;
321 }
322 tuple0 = PyTuple_New(0);
323 if (!tuple0)
324 goto exit;
325 for (i = 0; i < xsperms_n; i++) {
326 /* Domain the permissions apply to. */
327 int dom = 0;
328 /* Read/write perms. Set these. */
329 int p_read = 0, p_write = 0;
330 PyObject *p = PyList_GetItem(perms, i);
331 if (!PyArg_ParseTupleAndKeywords(tuple0, p, perm_spec, perm_names,
332 &dom, &p_read, &p_write))
333 goto exit;
334 xsperms[i].id = dom;
335 if (p_read)
336 xsperms[i].perms |= XS_PERM_READ;
337 if (p_write)
338 xsperms[i].perms |= XS_PERM_WRITE;
339 }
340 xsval = xs_set_permissions(xh, path, xsperms, xsperms_n);
341 val = pyvalue_int(xsval);
342 exit:
343 Py_XDECREF(tuple0);
344 if (xsperms)
345 free(xsperms);
346 return val;
347 }
349 #define xspy_watch_doc "\n" \
350 "Watch a path, get notifications when it changes.\n" \
351 " path [string] : xenstore path.\n" \
352 " token [string] : returned in watch notification.\n" \
353 "\n" \
354 "Returns: [int] 0 on success.\n" \
355 "Raises RuntimeError on error.\n" \
356 "\n"
358 static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds)
359 {
360 static char *kwd_spec[] = { "path", "token", NULL };
361 static char *arg_spec = "s|is";
362 char *path = NULL;
363 char *token = "";
365 struct xs_handle *xh = xshandle(self);
366 PyObject *val = NULL;
367 int xsval = 0;
369 if (!xh)
370 goto exit;
371 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
372 &path, &token))
373 goto exit;
374 xsval = xs_watch(xh, path, token);
375 val = pyvalue_int(xsval);
376 exit:
377 return val;
378 }
380 #define xspy_read_watch_doc "\n" \
381 "Read a watch notification.\n" \
382 "The notification must be acknowledged by passing\n" \
383 "the token to acknowledge_watch().\n" \
384 " path [string]: xenstore path.\n" \
385 "\n" \
386 "Returns: [tuple] (path, token).\n" \
387 "Raises RuntimeError on error.\n" \
388 "\n"
390 static PyObject *xspy_read_watch(PyObject *self, PyObject *args,
391 PyObject *kwds)
392 {
393 static char *kwd_spec[] = { NULL };
394 static char *arg_spec = "";
396 struct xs_handle *xh = xshandle(self);
397 PyObject *val = NULL;
398 char **xsval = NULL;
400 if (!xh)
401 goto exit;
402 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
403 goto exit;
404 xsval = xs_read_watch(xh);
405 if (!xsval) {
406 val = PyErr_SetFromErrno(PyExc_RuntimeError);
407 goto exit;
408 }
409 /* Create tuple (path, token). */
410 val = Py_BuildValue("(ss)", xsval[0], xsval[1]);
411 exit:
412 if (xsval)
413 free(xsval);
414 return val;
415 }
417 #define xspy_acknowledge_watch_doc "\n" \
418 "Acknowledge a watch notification that has been read.\n" \
419 " token [string] : from the watch notification\n" \
420 "\n" \
421 "Returns: [int] 0 on success.\n" \
422 "Raises RuntimeError on error.\n" \
423 "\n"
425 static PyObject *xspy_acknowledge_watch(PyObject *self, PyObject *args,
426 PyObject *kwds)
427 {
428 static char *kwd_spec[] = { "token", NULL };
429 static char *arg_spec = "s";
430 char *token;
432 struct xs_handle *xh = xshandle(self);
433 PyObject *val = NULL;
434 int xsval = 0;
436 if (!xh)
437 goto exit;
438 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token))
439 goto exit;
440 xsval = xs_acknowledge_watch(xh, token);
441 val = pyvalue_int(xsval);
442 exit:
443 return val;
444 }
446 #define xspy_unwatch_doc "\n" \
447 "Stop watching a path.\n" \
448 " path [string] : xenstore path.\n" \
449 " token [string] : token from the watch.\n" \
450 "\n" \
451 "Returns: [int] 0 on success.\n" \
452 "Raises RuntimeError on error.\n" \
453 "\n"
455 static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
456 {
457 static char *kwd_spec[] = { "path", "token", NULL };
458 static char *arg_spec = "s|s";
459 char *path = NULL;
460 char *token = "";
462 struct xs_handle *xh = xshandle(self);
463 PyObject *val = NULL;
464 int xsval = 0;
466 if (!xh)
467 goto exit;
468 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path,
469 &token))
470 goto exit;
471 xsval = xs_unwatch(xh, path, token);
472 val = pyvalue_int(xsval);
473 exit:
474 return val;
475 }
477 #define xspy_transaction_start_doc "\n" \
478 "Start a transaction on a path.\n" \
479 "Only one transaction can be active at a time.\n" \
480 " path [string]: xenstore path.\n" \
481 "\n" \
482 "Returns: [int] 0 on success.\n" \
483 "Raises RuntimeError on error.\n" \
484 "\n"
486 static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
487 PyObject *kwds)
488 {
489 static char *kwd_spec[] = { "path", NULL };
490 static char *arg_spec = "s|";
491 char *path = NULL;
493 struct xs_handle *xh = xshandle(self);
494 PyObject *val = NULL;
495 int xsval = 0;
497 if (!xh)
498 goto exit;
499 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
500 goto exit;
501 xsval = xs_transaction_start(xh, path);
502 val = pyvalue_int(xsval);
503 exit:
504 return val;
505 }
507 #define xspy_transaction_end_doc "\n" \
508 "End the current transaction.\n" \
509 "Attempts to commit the transaction unless abort is true.\n" \
510 " abort [int]: abort flag (default 0).\n" \
511 "\n" \
512 "Returns: [int] 0 on success.\n" \
513 "Raises RuntimeError on error.\n" \
514 "\n"
516 static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
517 PyObject *kwds)
518 {
519 static char *kwd_spec[] = { "abort", NULL };
520 static char *arg_spec = "|i";
521 int abort = 0;
523 struct xs_handle *xh = xshandle(self);
524 PyObject *val = NULL;
525 int xsval = 0;
527 if (!xh)
528 goto exit;
529 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
530 goto exit;
531 xsval = xs_transaction_end(xh, abort);
532 val = pyvalue_int(xsval);
533 exit:
534 return val;
535 }
537 #define xspy_introduce_domain_doc "\n" \
538 "Tell xenstore about a domain so it can talk to it.\n" \
539 " dom [int] : domain id\n" \
540 " page [long] : address of domain's xenstore page\n" \
541 " port [int] : port the domain is using for xenstore\n" \
542 " path [string]: path to the domain's data in xenstore\n" \
543 "\n" \
544 "Returns: [int] 0 on success.\n" \
545 "Raises RuntimeError on error.\n" \
546 "\n"
548 static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args,
549 PyObject *kwds)
550 {
551 static char *kwd_spec[] = { "dom", "page", "port", "path", NULL };
552 static char *arg_spec = "iiis|";
553 domid_t dom = 0;
554 unsigned long page = 0;
555 unsigned int port = 0;
556 char *path = NULL;
558 struct xs_handle *xh = xshandle(self);
559 PyObject *val = NULL;
560 int xsval = 0;
562 if (!xh)
563 goto exit;
564 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
565 &dom, &page, &port, &path))
566 goto exit;
567 xsval = xs_introduce_domain(xh, dom, page, port, path);
568 val = pyvalue_int(xsval);
569 exit:
570 return val;
571 }
573 #define xspy_release_domain_doc "\n" \
574 "Tell xenstore to release its channel to a domain.\n" \
575 "Unless this is done the domain will not be released.\n" \
576 " dom [int]: domain id\n" \
577 "\n" \
578 "Returns: [int] 0 on success.\n" \
579 "Raises RuntimeError on error.\n" \
580 "\n"
582 static PyObject *xspy_release_domain(PyObject *self, PyObject *args,
583 PyObject *kwds)
584 {
585 static char *kwd_spec[] = { "dom", NULL };
586 static char *arg_spec = "i|";
587 domid_t dom;
589 struct xs_handle *xh = xshandle(self);
590 PyObject *val = NULL;
591 int xsval = 0;
593 if (!xh)
594 goto exit;
595 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
596 &dom))
597 goto exit;
598 xsval = xs_release_domain(xh, dom);
599 val = pyvalue_int(xsval);
600 exit:
601 return val;
602 }
604 #define xspy_close_doc "\n" \
605 "Close the connection to xenstore.\n" \
606 "\n" \
607 "Returns: [int] 0 on success.\n" \
608 "Raises RuntimeError on error.\n" \
609 "\n"
611 static PyObject *xspy_close(PyObject *self, PyObject *args, PyObject *kwds)
612 {
613 static char *kwd_spec[] = { NULL };
614 static char *arg_spec = "";
616 struct xs_handle *xh = xshandle(self);
617 PyObject *val = NULL;
618 int xsval = 1;
620 if (!xh)
621 goto exit;
622 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
623 goto exit;
624 xs_daemon_close(xh);
625 ((XsHandle*)self)->xh = NULL;
626 val = pyvalue_int(xsval);
627 exit:
628 return val;
629 }
631 #define xspy_shutdown_doc "\n" \
632 "Shutdown the xenstore daemon.\n" \
633 "\n" \
634 "Returns: [int] 0 on success.\n" \
635 "Raises RuntimeError on error.\n" \
636 "\n"
638 static PyObject *xspy_shutdown(PyObject *self, PyObject *args, PyObject *kwds)
639 {
640 static char *kwd_spec[] = { NULL };
641 static char *arg_spec = "";
643 struct xs_handle *xh = xshandle(self);
644 PyObject *val = NULL;
645 int xsval = 0;
647 if (!xh)
648 goto exit;
649 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
650 goto exit;
651 xsval = xs_shutdown(xh);
652 val = pyvalue_int(xsval);
653 exit:
654 return val;
655 }
657 #define xspy_fileno_doc "\n" \
658 "Get the file descriptor of the xenstore socket.\n" \
659 "Allows an xs object to be passed to select().\n" \
660 "\n" \
661 "Returns: [int] file descriptor.\n" \
662 "\n"
664 static PyObject *xspy_fileno(PyObject *self, PyObject *args, PyObject *kwds)
665 {
666 static char *kwd_spec[] = { NULL };
667 static char *arg_spec = "";
669 struct xs_handle *xh = xshandle(self);
670 PyObject *val = NULL;
672 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
673 goto exit;
674 val = PyInt_FromLong((xh ? xs_fileno(xh) : -1));
675 exit:
676 return val;
677 }
679 #define XSPY_METH(_name) { \
680 .ml_name = #_name, \
681 .ml_meth = (PyCFunction) xspy_ ## _name, \
682 .ml_flags = (METH_VARARGS | METH_KEYWORDS), \
683 .ml_doc = xspy_ ## _name ## _doc }
685 static PyMethodDef xshandle_methods[] = {
686 XSPY_METH(read),
687 XSPY_METH(write),
688 XSPY_METH(ls),
689 XSPY_METH(mkdir),
690 XSPY_METH(rm),
691 XSPY_METH(get_permissions),
692 XSPY_METH(set_permissions),
693 XSPY_METH(watch),
694 XSPY_METH(read_watch),
695 XSPY_METH(acknowledge_watch),
696 XSPY_METH(unwatch),
697 XSPY_METH(transaction_start),
698 XSPY_METH(transaction_end),
699 XSPY_METH(introduce_domain),
700 XSPY_METH(release_domain),
701 XSPY_METH(close),
702 XSPY_METH(shutdown),
703 XSPY_METH(fileno),
704 { /* Terminator. */ },
705 };
707 static PyObject *xshandle_getattr(PyObject *self, char *name)
708 {
709 PyObject *val = NULL;
710 val = Py_FindMethod(xshandle_methods, self, name);
711 return val;
712 }
714 static void xshandle_dealloc(PyObject *self)
715 {
716 XsHandle *xh = (XsHandle*)self;
717 if (xh->xh) {
718 xs_daemon_close(xh->xh);
719 xh->xh = NULL;
720 }
721 PyObject_Del(self);
722 }
724 static PyTypeObject xshandle_type = {
725 PyObject_HEAD_INIT(&PyType_Type)
726 0,
727 "xshandle",
728 sizeof(XsHandle),
729 0,
730 xshandle_dealloc, /* tp_dealloc */
731 NULL, /* tp_print */
732 xshandle_getattr, /* tp_getattr */
733 NULL, /* tp_setattr */
734 NULL, /* tp_compare */
735 NULL, /* tp_repr */
736 NULL, /* tp_as_number */
737 NULL, /* tp_as_sequence */
738 NULL, /* tp_as_mapping */
739 NULL /* tp_hash */
740 };
742 static PyObject *xshandle_open(PyObject *self, PyObject *args, PyObject *kwds)
743 {
744 static char *kwd_spec[] = { "readonly", NULL };
745 static char *arg_spec = "|i";
746 int readonly = 0;
748 XsHandle *xsh = NULL;
749 PyObject *val = NULL;
751 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
752 &readonly))
753 goto exit;
755 xsh = PyObject_New(XsHandle, &xshandle_type);
756 if (!xsh)
757 goto exit;
758 xsh->xh = (readonly ? xs_daemon_open_readonly() : xs_daemon_open());
759 if (!xsh->xh) {
760 PyObject_Del(xsh);
761 val = pyvalue_int(0);
762 goto exit;
763 }
764 val = (PyObject *)xsh;
765 exit:
766 return val;
767 }
769 static PyMethodDef xs_methods[] = {
770 { .ml_name = "open",
771 .ml_meth = (PyCFunction)xshandle_open,
772 .ml_flags = (METH_VARARGS | METH_KEYWORDS),
773 .ml_doc = "\n"
774 "Open a connection to the xenstore daemon.\n"
775 "Returns: xs connection object.\n"
776 "Raises RuntimeError on error.\n"
777 "\n"
778 },
779 { /* Terminator. */ }
780 };
782 PyMODINIT_FUNC initxs (void)
783 {
784 PyObject *module;
786 module = Py_InitModule(PYPKG, xs_methods);
787 }