3 * System-specific functionality
5 * (c) 2019 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the Python interface to mLib.
12 * mLib/Python is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
17 * mLib/Python is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with mLib/Python. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 /*----- Header files ------------------------------------------------------*/
30 #include "mLib-python.h"
32 /*----- Main code ---------------------------------------------------------*/
34 static int getint(PyObject *obj, int *i_out)
40 t = PyNumber_Index(obj); if (!t) goto end;
41 i = PyInt_AsLong(t); if (i == -1 && PyErr_Occurred()) goto end;
42 if (INT_MIN > i || i > INT_MAX) OVFERR("out of range");
50 static int convfd(PyObject *obj, void *p)
56 if (getint(obj, fd_out)) {
58 t = PyObject_CallMethod(obj, "fileno", 0); if (!t) goto end;
59 if (getint(t, fd_out)) goto end;
67 static PyObject *meth_detachtty(PyObject *me)
68 { detachtty(); RETURN_NONE; }
70 static PyObject *meth_daemonize(PyObject *me)
72 if (daemonize()) OSERR(0);
78 static PyObject *meth_fdflags(PyObject *me, PyObject *arg, PyObject *kw)
81 unsigned fbic = 0, fxor = 0, fdbic = 0, fdxor = 0;
82 static const char *const kwlist[] =
83 { "file", "fbic", "fxor", "fdbic", "fdxor", 0 };
85 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&O&O&O&:fdflags", KWLIST,
87 convuint, &fbic, convuint, &fxor,
88 convuint, &fdbic, convuint, &fdxor))
90 if (fdflags(fd, fbic, fxor, fdbic, fdxor)) OSERR(0);
96 static PyObject *meth_fdsend(PyObject *me, PyObject *arg, PyObject *kw)
102 static const char *const kwlist[] = { "sock", "file", "buffer", 0 };
104 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&O&:fdsend", KWLIST,
105 convfd, &sock, convfd, &fd,
108 n = fdpass_send(sock, fd, buf.p, buf.sz); if (n < 0) OSERR(0);
109 rc = PyInt_FromLong(n);
114 static PyObject *meth_fdrecv(PyObject *me, PyObject *arg, PyObject *kw)
120 PyObject *buf = 0, *rc = 0;
121 static const char *const kwlist[] = { "sock", "size", 0 };
123 if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&:fdrecv", KWLIST,
124 convfd, &sock, convszt, &sz))
126 BIN_PREPAREWRITE(buf, p, sz);
127 n = fdpass_recv(sock, &fd, p, sz); if (n < 0) OSERR(0);
128 BIN_DONEWRITE(buf, n);
129 rc = Py_BuildValue("(iN)", fd, buf); buf = 0;
135 static PyObject *meth_mdup(PyObject *me, PyObject *arg)
138 PyObject *t = 0, *u = 0, *rc = 0;
144 if (!PyArg_ParseTuple(arg, "O:mdup", &v)) goto end;
145 n = PySequence_Size(v); if (n < 0) goto end;
146 vv = xmalloc(n*sizeof(*vv));
147 for (i = 0; i < n; i++) {
148 t = PySequence_GetItem(v, i); if (!t) goto end;
149 m = PySequence_Size(t); if (m < 0) goto end;
150 if (m != 2) VALERR("expected a list of pairs");
152 u = PySequence_GetItem(t, 0);
153 if (getint(u, &vv[i].cur)) goto end;
156 u = PySequence_GetItem(t, 1);
157 if (getint(u, &vv[i].want)) goto end;
165 for (i = 0; i < n; i++) {
166 t = Py_BuildValue("(ii)", vv[i].cur, vv[i].want);
167 if (PySequence_SetItem(v, i, t)) goto end;
172 rc = v; Py_INCREF(rc);
175 Py_XDECREF(t); Py_XDECREF(u);
179 static const PyMethodDef methods[] = {
180 #define METHNAME(name) meth_##name
181 NAMETH(detachtty, "detachtty(): fork, detatch controlling terminal")
182 NAMETH(daemonize, "daemonize(): fork and become a daemon")
183 KWMETH(fdflags, "fdflags(FILE, [fbic = 0], [fxor = 0], "
184 "[fdbic = 0], [fdxor = 0])")
185 KWMETH(fdsend, "fdsend(FILE, FD, BUFFER) -> N")
186 KWMETH(fdrecv, "fdrecv(FILE, SIZE) -> FD, BUFFER")
187 METH (mdup, "mdup(LIST) -> LIST:\n"
188 " LIST is a list (mutable sequence) of pairs (CUR, WANT). Duplicate\n"
189 " each CUR file descriptor as WANT (may be -1 to mean `don't care'),\n"
190 " closing original CUR. Works even if there are cycles. LIST is\n"
191 " updated in place with CUR reflecting the new file descriptors even\n"
192 " on error. Returns the same LIST on success.")
197 void sys_pyinit(void)
202 void sys_pyinsert(PyObject *mod)
206 /*----- That's all, folks -------------------------------------------------*/